diff options
40 files changed, 263 insertions, 124 deletions
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index d75680b4b5..d41bfc009e 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -146,7 +146,7 @@ jobs: - name: Open and close editor if: ${{ matrix.proj-test }} run: | - VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy -e -q --path test_project 2>&1 | tee sanitizers_log.txt || true + VK_ICD_FILENAMES=$(pwd)/vk_swiftshader_icd.json DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true misc/scripts/check_ci_log.py sanitizers_log.txt # Run test project diff --git a/core/os/thread.cpp b/core/os/thread.cpp index f80e8f4bb3..c8072b7280 100644 --- a/core/os/thread.cpp +++ b/core/os/thread.cpp @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#include "platform_config.h" #ifndef PLATFORM_THREAD_OVERRIDE // See details in thread.h #include "thread.h" diff --git a/core/os/thread.h b/core/os/thread.h index f4e46059ad..3382dd81f9 100644 --- a/core/os/thread.h +++ b/core/os/thread.h @@ -28,6 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#include "platform_config.h" // Define PLATFORM_THREAD_OVERRIDE in your platform's `platform_config.h` // to use a custom Thread implementation defined in `platform/[your_platform]/platform_thread.h` // Overriding the platform implementation is required in some proprietary platforms diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index 3350735ca2..b9373676e2 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -157,7 +157,7 @@ Speed in pixels per second of the camera's smoothing effect when [member smoothing_enabled] is [code]true[/code]. </member> <member name="zoom" type="Vector2" setter="set_zoom" getter="get_zoom" default="Vector2(1, 1)"> - The camera's zoom relative to the viewport. Values larger than [code]Vector2(1, 1)[/code] zoom out and smaller values zoom in. For an 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. + The camera's zoom. A zoom of [code]Vector(2, 2)[/code] doubles the size seen in the viewport. A zoom of [code]Vector(0.5, 0.5)[/code] halves the size seen in the viewport. </member> </members> <constants> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index d71762801c..c7451509f3 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -355,6 +355,13 @@ Returns the mouse's position in this [CanvasItem] using the local coordinate system of this [CanvasItem]. </description> </method> + <method name="get_screen_transform" qualifiers="const"> + <return type="Transform2D" /> + <description> + Returns the transform of this [CanvasItem] in global screen coordinates (i.e. taking window position into account). Mostly useful for editor plugins. + Equals to [method get_global_transform] if the window is embedded (see [member Viewport.gui_embed_subwindows]). + </description> + </method> <method name="get_transform" qualifiers="const"> <return type="Transform2D" /> <description> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 97fd584ed1..3163ac5610 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -417,6 +417,19 @@ Returns the position and size of the control relative to the top-left corner of the parent Control. See [member position] and [member size]. </description> </method> + <method name="get_screen_position" qualifiers="const"> + <return type="Vector2" /> + <description> + Returns the position of this [Control] in global screen coordinates (i.e. taking window position into account). Mostly useful for editor plugins. + Equals to [member global_position] if the window is embedded (see [member Viewport.gui_embed_subwindows]). + Example usage for showing a popup: + [codeblock] + popup_menu.position = get_screen_position() + get_local_mouse_position() + popup_menu.reset_size() + popup_menu.popup() + [/codeblock] + </description> + </method> <method name="get_theme_color" qualifiers="const"> <return type="Color" /> <argument index="0" name="name" type="StringName" /> diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 50990b5320..213dafa074 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -149,6 +149,17 @@ Once finished with your RID, you will want to free the RID using the RenderingServer's [method free_rid] static method. </description> </method> + <method name="canvas_item_add_animation_slice"> + <return type="void" /> + <argument index="0" name="item" type="RID" /> + <argument index="1" name="animation_length" type="float" /> + <argument index="2" name="slice_begin" type="float" /> + <argument index="3" name="slice_end" type="float" /> + <argument index="4" name="offset" type="float" default="0.0" /> + <description> + Subsequent drawing commands will be ignored unless they fall within the specified animation slice. This is a faster way to implement animations that loop on background rather than redrawing constantly. + </description> + </method> <method name="canvas_item_add_circle"> <return type="void" /> <argument index="0" name="item" type="RID" /> diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index ce61f51b9a..a72e7f1eb0 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -130,11 +130,6 @@ Removes the focus from the currently focused [Control] within this viewport. If no [Control] has the focus, does nothing. </description> </method> - <method name="is_embedding_subwindows" qualifiers="const"> - <return type="bool" /> - <description> - </description> - </method> <method name="is_input_handled" qualifiers="const"> <return type="bool" /> <description> @@ -219,7 +214,8 @@ <member name="gui_disable_input" type="bool" setter="set_disable_input" getter="is_input_disabled" default="false"> If [code]true[/code], the viewport will not receive input events. </member> - <member name="gui_embed_subwindows" type="bool" setter="set_embed_subwindows_hint" getter="get_embed_subwindows_hint" default="false"> + <member name="gui_embed_subwindows" type="bool" setter="set_embedding_subwindows" getter="is_embedding_subwindows" default="false"> + If [code]true[/code], sub-windows (popups and dialogs) will be embedded inside application window as control-like nodes. If [code]false[/code], they will appear as separate windows handled by the operating system. </member> <member name="gui_snap_controls_to_pixels" type="bool" setter="set_snap_controls_to_pixels" getter="is_snap_controls_to_pixels_enabled" default="true"> If [code]true[/code], the GUI controls on the viewport will lay pixel perfectly. diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp index 853278c5fc..7b72e09bd7 100644 --- a/editor/editor_fonts.cpp +++ b/editor/editor_fonts.cpp @@ -64,8 +64,8 @@ m_name->add_data(FontTamilBold); \ m_name->add_data(FontTeluguBold); \ m_name->add_data(FontThaiBold); \ - m_name->add_data(FontJapanese); \ - m_name->add_data(FontFallback); + m_name->add_data(FontJapaneseBold); \ + m_name->add_data(FontFallbackBold); #define MAKE_DEFAULT_FONT(m_name, m_variations) \ Ref<Font> m_name; \ @@ -206,7 +206,8 @@ void editor_register_fonts(Ref<Theme> p_theme) { break; } - int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE; + const int default_font_size = int(EDITOR_GET("interface/editor/main_font_size")) * EDSCALE; + const float embolden_strength = 0.6; String custom_font_path = EditorSettings::get_singleton()->get("interface/editor/main_font"); Ref<FontData> CustomFont; @@ -226,6 +227,11 @@ void editor_register_fonts(Ref<Theme> p_theme) { EditorSettings::get_singleton()->set_manually("interface/editor/main_font_bold", ""); } + if (CustomFont.is_valid() && !CustomFontBold.is_valid()) { + CustomFontBold = CustomFont->duplicate(); + CustomFontBold->set_embolden(embolden_strength); + } + /* Custom source code font */ String custom_font_path_source = EditorSettings::get_singleton()->get("interface/editor/code_font"); @@ -268,6 +274,11 @@ void editor_register_fonts(Ref<Theme> p_theme) { 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); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 20b8079689..9efd942a51 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -882,7 +882,7 @@ void EditorProperty::menu_option(int p_option) { emit_changed(property, InspectorDock::get_inspector_singleton()->get_property_clipboard()); } break; case MENU_COPY_PROPERTY_PATH: { - DisplayServer::get_singleton()->clipboard_set(property); + DisplayServer::get_singleton()->clipboard_set(property_path); } break; case MENU_PIN_VALUE: { emit_signal(SNAME("property_pinned"), property, !pinned); @@ -2314,6 +2314,7 @@ void EditorInspector::_parse_added_editors(VBoxContainer *current_vbox, Ref<Edit if (F.properties.size() == 1) { //since it's one, associate: ep->property = F.properties[0]; + ep->property_path = property_prefix + F.properties[0]; ep->property_usage = 0; } @@ -2874,6 +2875,7 @@ void EditorInspector::update_tree() { if (F.properties.size() == 1) { //since it's one, associate: ep->property = F.properties[0]; + ep->property_path = property_prefix + F.properties[0]; ep->property_usage = p.usage; //and set label? } diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h index c1454ad84c..3c482a07e7 100644 --- a/editor/editor_inspector.h +++ b/editor/editor_inspector.h @@ -68,6 +68,7 @@ private: friend class EditorInspector; Object *object; StringName property; + String property_path; int property_usage; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 5fe2172771..7251530fdc 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -701,7 +701,7 @@ void EditorNode::_notification(int p_what) { } break; case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? TabBar::CLOSE_BUTTON_SHOW_ALWAYS : TabBar::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); + scene_tabs->set_tab_close_display_policy((TabBar::CloseButtonDisplayPolicy)EDITOR_GET("interface/scene_tabs/display_close_button").operator int()); bool theme_changed = EditorSettings::get_singleton()->check_changed_settings_in_group("interface/theme") || @@ -6016,7 +6016,6 @@ EditorNode::EditorNode() { ClassDB::set_class_enabled("RootMotionView", true); // defs here, use EDITOR_GET in logic - EDITOR_DEF_RST("interface/scene_tabs/always_show_close_button", false); EDITOR_DEF("interface/editor/save_on_focus_loss", false); EDITOR_DEF("interface/editor/show_update_spinner", false); EDITOR_DEF("interface/editor/update_continuously", false); @@ -6242,7 +6241,7 @@ EditorNode::EditorNode() { scene_tabs->set_select_with_rmb(true); scene_tabs->add_tab("unsaved"); scene_tabs->set_tab_alignment(TabBar::ALIGNMENT_LEFT); - scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? TabBar::CLOSE_BUTTON_SHOW_ALWAYS : TabBar::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); + scene_tabs->set_tab_close_display_policy((TabBar::CloseButtonDisplayPolicy)EDITOR_GET("interface/scene_tabs/display_close_button").operator int()); scene_tabs->set_max_tab_width(int(EDITOR_GET("interface/scene_tabs/maximum_width")) * EDSCALE); scene_tabs->set_drag_to_rearrange_enabled(true); scene_tabs->connect("tab_changed", callable_mp(this, &EditorNode::_scene_tab_changed)); @@ -6292,7 +6291,7 @@ EditorNode::EditorNode() { scene_root_parent->set_v_size_flags(Control::SIZE_EXPAND_FILL); scene_root = memnew(SubViewport); - scene_root->set_embed_subwindows_hint(true); + scene_root->set_embedding_subwindows(true); scene_root->set_disable_3d(true); scene_root->set_disable_input(true); diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index 38003ab2f4..20327cb867 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -69,7 +69,9 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { // The map name and value definition format should be kept synced with the regex. capitalize_string_remaps["2d"] = "2D"; capitalize_string_remaps["3d"] = "3D"; + capitalize_string_remaps["Aa"] = "AA"; capitalize_string_remaps["Adb"] = "ADB"; + capitalize_string_remaps["Ao"] = "AO"; capitalize_string_remaps["Bptc"] = "BPTC"; capitalize_string_remaps["Bvh"] = "BVH"; capitalize_string_remaps["Csg"] = "CSG"; @@ -81,21 +83,27 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["Fbx"] = "FBX"; capitalize_string_remaps["Fps"] = "FPS"; capitalize_string_remaps["Fov"] = "FOV"; + capitalize_string_remaps["Fsr"] = "FSR"; capitalize_string_remaps["Fs"] = "FS"; capitalize_string_remaps["Fxaa"] = "FXAA"; capitalize_string_remaps["Ggx"] = "GGX"; + capitalize_string_remaps["Gi"] = "GI"; capitalize_string_remaps["Gdscript"] = "GDScript"; capitalize_string_remaps["Gles 2"] = "GLES2"; capitalize_string_remaps["Gles 3"] = "GLES3"; - capitalize_string_remaps["Gi Probe"] = "GI Probe"; + capitalize_string_remaps["Gpu"] = "GPU"; + capitalize_string_remaps["Gui"] = "GUI"; capitalize_string_remaps["Hdr"] = "HDR"; capitalize_string_remaps["Hidpi"] = "hiDPI"; + capitalize_string_remaps["Http"] = "HTTP"; capitalize_string_remaps["Ik"] = "IK"; capitalize_string_remaps["Ios"] = "iOS"; capitalize_string_remaps["Kb"] = "KB"; + capitalize_string_remaps["Lod"] = "LOD"; capitalize_string_remaps["Msaa"] = "MSAA"; capitalize_string_remaps["Macos"] = "macOS"; capitalize_string_remaps["Opentype"] = "OpenType"; + capitalize_string_remaps["Openxr"] = "OpenXR"; capitalize_string_remaps["Png"] = "PNG"; capitalize_string_remaps["Pvs"] = "PVS"; capitalize_string_remaps["Pvrtc"] = "PVRTC"; @@ -104,16 +112,23 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["Srgb"] = "sRGB"; capitalize_string_remaps["Ssao"] = "SSAO"; capitalize_string_remaps["Ssl"] = "SSL"; + capitalize_string_remaps["Ssil"] = "SSIL"; capitalize_string_remaps["Ssh"] = "SSH"; + capitalize_string_remaps["Sdf"] = "SDF"; capitalize_string_remaps["Sdk"] = "SDK"; capitalize_string_remaps["Tcp"] = "TCP"; + capitalize_string_remaps["Url"] = "URL"; capitalize_string_remaps["Uv 1"] = "UV1"; capitalize_string_remaps["Uv 2"] = "UV2"; + capitalize_string_remaps["Uv"] = "UV"; + capitalize_string_remaps["Uwp"] = "UWP"; capitalize_string_remaps["Vram"] = "VRAM"; capitalize_string_remaps["Vsync"] = "V-Sync"; capitalize_string_remaps["Vector 2"] = "Vector2"; + capitalize_string_remaps["Webp"] = "WebP"; capitalize_string_remaps["Webrtc"] = "WebRTC"; capitalize_string_remaps["Websocket"] = "WebSocket"; + capitalize_string_remaps["Xr"] = "XR"; } EditorPropertyNameProcessor::~EditorPropertyNameProcessor() { diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index 00b6b84461..2d80fe85f8 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -460,6 +460,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "interface/theme/custom_theme", "", "*.res,*.tres,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED) // Scene tabs + EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/scene_tabs/display_close_button", 1, "Never,If Tab Active,Always"); // TabBar::CloseButtonDisplayPolicy _initial_set("interface/scene_tabs/show_thumbnail_on_hover", true); EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_RANGE, "interface/scene_tabs/maximum_width", 350, "0,9999,1", PROPERTY_USAGE_DEFAULT) _initial_set("interface/scene_tabs/show_script_button", false); diff --git a/editor/icons/ViewportSpeed.svg b/editor/icons/ViewportSpeed.svg index 8fceaffd52..57292e2e91 100644 --- a/editor/icons/ViewportSpeed.svg +++ b/editor/icons/ViewportSpeed.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 4.2333333 4.2333333" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1.5875 0c-.28858 0-.52917.24059-.52917.52917v.61132c-.085589-.051-.18113-.0891-.28525-.0853-.34849.0127-.5952.37346-.48059.70278l.26355.79066c.048664.14623.15979.24805.29249.30644l-.60927.40669c-.13121.0845-.22102.22389-.24133.3633-.020312.13941.017471.26985.087333.37465s.17614.19045.31264.22532c.13634.0348.29946.006.42788-.0827h.0005159l1.0852-.72348.26097.52192c.11682.23391.39274.34829.64079.26561l.79375-.26458-.00775.003c.15105-.0454.27732-.15615.33486-.2863.057538-.13015.055144-.26773.014986-.38809-.03156-.0946-.10972-.1687-.19275-.23617.069099-.0546.1445-.10364.18035-.19325.051761-.12941.045257-.29292-.02377-.43098l-.26459-.52946c-.089407-.17933-.27348-.29308-.47335-.29305h-.1111c.052029-.0817.1111-.16214.1111-.26458v-.79375c0-.28858-.24059-.52917-.52917-.52917z"/><path d="m1.5875.26458c-.14658 0-.26458.118-.26458.26459v.79375c0 .14658.118.26458.26458.26458h.26458v.262a.26461.26461 0 0 0 -.083716.0165l-.5426.18086-.18087-.5426a.26461.26461 0 0 0 -.262-.18448.26461.26461 0 0 0 -.2403.3514l.26458.79375a.26461.26461 0 0 0 .33486.16743l.44545-.14831v.16174c0 .0108.00495.02.0062.0305l-1.2113.80771a.26461.26461 0 1 0 .29352.44028l1.3379-.89194.39532.79014a.26461.26461 0 0 0 .32039.1328l.79375-.26458a.26461.26461 0 1 0 -.16743-.50175l-.57619.19172-.25787-.51625c.072998-.047.12402-.12495.12402-.21859v-.26458h.36587l.1912.38292a.26461.26461 0 1 0 .47336-.23668l-.26458-.52916a.26461.26461 0 0 0 -.23668-.14625h-.79375v-.26458h.26458c.14658 0 .26458-.118.26458-.26458v-.79375c0-.14659-.118-.26459-.26458-.26459zm0 .52917h.26458v.52917h-.26458z" fill="#fff" fill-opacity=".99608"/></svg> +<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><g stroke-width="3.77953"><path d="m6.0285136 0c-1.0906961 0-2.0000127.90931655-2.0000127 2.0000126v2.3105008c-.3234859-.1927559-.6845858-.3367559-1.0781102-.3223937-1.3171276.048-2.24957487 1.4115024-1.8164032 2.6561764l.9960945 2.9883213c.183927.5526806.6039307.9375116 1.1054741 1.1581986l-2.30275287 1.537096c-.49591181.31937-.83535119.846198-.91211339 1.373102-.07676977.526904.06603212 1.019906.33007748 1.416.26404536.396095.66572598.719811 1.18163158.851603.5153008.131528 1.1318173.02268 1.6171842-.312566h.00195l4.1015433-2.734413.9863434 1.972611c.4415244.884069 1.4843716 1.316372 2.4218832 1.00388l3-.999987-.02929.01134c.570898-.17159 1.048139-.590173 1.265613-1.082078.217466-.491906.208418-1.011893.05664-1.466797-.119282-.357543-.41469-.637606-.728504-.892611.261162-.206362.546142-.39171.681638-.730394.195632-.489109.17105-1.1070991-.08984-1.6289007l-1.000027-2.0011107c-.337916-.6777827-1.033625-1.1077039-1.789039-1.1075905h-.419906c.196645-.3087874.419906-.6128126.419906-.9999874v-3.0000001c0-1.09069605-.909317-2.0000126-2.000012-2.0000126z"/><path d="m6.0285136.99998741c-.5540032 0-.9999874.44598429-.9999874 1.00002519v3.0000001c0 .5540031.4459842.9999874.9999874.9999874h.9999874v.9902362a1.0001008 1.0001008 0 0 0 -.316407.062362l-2.0507716.6835656-.6836032-2.0507717a1.0001008 1.0001008 0 0 0 -.9902362-.6972473 1.0001008 1.0001008 0 0 0 -.9082205 1.328126l.9999874 3.0000001a1.0001008 1.0001008 0 0 0 1.2656126.6328063l1.6835906-.5605418v.6113008c0 .040819.018709.075591.023433.1152757l-4.5781418 3.052762a1.0001008 1.0001008 0 1 0 1.1093669 1.664051l5.05663-3.371112 1.4941228 2.986356a1.0001008 1.0001008 0 0 0 1.210922.501921l3.000001-.999987a1.0001008 1.0001008 0 1 0 -.632807-1.896378l-2.177726.724611-.9746262-1.951182c.275898-.177637.4687372-.472252.4687372-.8261665v-.9999874h1.382815l.722646 1.4472569a1.0001246 1.0001246 0 1 0 1.789077-.8945388l-.999987-1.9999748a1.0001008 1.0001008 0 0 0 -.894539-.5527559h-2.9999995v-.9999874h.9999875c.554003 0 .999987-.4459843.999987-.9999874v-3.0000001c0-.5540409-.445984-1.00002519-.999987-1.00002519zm0 2.00001259h.9999874v2.0000127h-.9999874z" fill="#fff" fill-opacity=".99608"/></g></svg> diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 5a2696fff1..22e0a3dabb 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -292,15 +292,14 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) _commit_action(); return true; } else { - Vector<Vector2> vertices2 = _get_polygon(insert.polygon); - pre_move_edit = vertices2; + pre_move_edit = vertices; edited_point = PosVertex(insert.polygon, insert.vertex + 1, xform.affine_inverse().xform(insert.pos)); - vertices2.insert(edited_point.vertex, edited_point.pos); + vertices.insert(edited_point.vertex, edited_point.pos); selected_point = Vertex(edited_point.polygon, edited_point.vertex); edge_point = PosVertex(); undo_redo->create_action(TTR("Insert Point")); - _action_set_polygon(insert.polygon, vertices2); + _action_set_polygon(insert.polygon, vertices); _commit_action(); return true; } diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 3927aaa438..a857a7509e 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -2690,27 +2690,27 @@ void Node3DEditorViewport::_notification(int p_what) { } } -static void draw_indicator_bar(Control &surface, real_t fill, const Ref<Texture2D> icon, const Ref<Font> font, int font_size, const String &text) { +static void draw_indicator_bar(Control &p_surface, real_t p_fill, const Ref<Texture2D> p_icon, const Ref<Font> p_font, int p_font_size, const String &p_text, const Color &p_color) { // Adjust bar size from control height - const Vector2 surface_size = surface.get_size(); + const Vector2 surface_size = p_surface.get_size(); const real_t h = surface_size.y / 2.0; const real_t y = (surface_size.y - h) / 2.0; const Rect2 r(10 * EDSCALE, y, 6 * EDSCALE, h); - const real_t sy = r.size.y * fill; + const real_t sy = r.size.y * p_fill; // Note: because this bar appears over the viewport, it has to stay readable for any background color // Draw both neutral dark and bright colors to account this - surface.draw_rect(r, Color(1, 1, 1, 0.2)); - surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6)); - surface.draw_rect(r.grow(1), Color(0, 0, 0, 0.7), false, Math::round(EDSCALE)); + p_surface.draw_rect(r, p_color * Color(1, 1, 1, 0.2)); + p_surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), p_color * Color(1, 1, 1, 0.6)); + p_surface.draw_rect(r.grow(1), Color(0, 0, 0, 0.7), false, Math::round(EDSCALE)); - const Vector2 icon_size = icon->get_size(); + const Vector2 icon_size = p_icon->get_size(); const Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2 * EDSCALE); - surface.draw_texture(icon, icon_pos); + p_surface.draw_texture(p_icon, icon_pos, p_color); // Draw text below the bar (for speed/zoom information). - surface.draw_string(font, Vector2(icon_pos.x, icon_pos.y + icon_size.y + 16 * EDSCALE), text, HORIZONTAL_ALIGNMENT_LEFT, -1.f, font_size); + 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)); } void Node3DEditorViewport::_draw() { @@ -2828,7 +2828,8 @@ void Node3DEditorViewport::_draw() { get_theme_icon(SNAME("ViewportSpeed"), SNAME("EditorIcons")), get_theme_font(SNAME("font"), SNAME("Label")), get_theme_font_size(SNAME("font_size"), SNAME("Label")), - vformat("%s u/s", String::num(freelook_speed).pad_decimals(precision))); + vformat("%s u/s", String::num(freelook_speed).pad_decimals(precision)), + Color(1.0, 0.95, 0.7)); } } else { @@ -2850,7 +2851,8 @@ void Node3DEditorViewport::_draw() { get_theme_icon(SNAME("ViewportZoom"), SNAME("EditorIcons")), get_theme_font(SNAME("font"), SNAME("Label")), get_theme_font_size(SNAME("font_size"), SNAME("Label")), - vformat("%s u", String::num(cursor.distance).pad_decimals(precision))); + vformat("%s u", String::num(cursor.distance).pad_decimals(precision)), + Color(0.7, 0.95, 1.0)); } } } diff --git a/main/main.cpp b/main/main.cpp index ccd48a9343..e0331f4945 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -273,7 +273,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" -h, --help Display this help message.\n"); OS::get_singleton()->print(" --version Display the version string.\n"); OS::get_singleton()->print(" -v, --verbose Use verbose stdout mode.\n"); - OS::get_singleton()->print(" --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n"); + OS::get_singleton()->print(" -q, --quiet Quiet mode, silences stdout messages. Errors are still displayed.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Run options:\n"); @@ -282,7 +282,7 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" -p, --project-manager Start the project manager, even if a project is auto-detected.\n"); OS::get_singleton()->print(" --debug-server <uri> Start the editor debug server (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007)\n"); #endif - OS::get_singleton()->print(" -q, --quit Quit after the first iteration.\n"); + OS::get_singleton()->print(" --quit Quit after the first iteration.\n"); OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n"); OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n"); OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n"); @@ -319,9 +319,8 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --rendering-driver <driver> Rendering driver (depends on display driver).\n"); OS::get_singleton()->print(" --gpu-index <device_index> Use a specific GPU (run with --verbose to get available device list).\n"); - OS::get_singleton()->print(" --text-driver <driver> Text driver (Fonts, BiDi, shaping)\n"); - + OS::get_singleton()->print(" --tablet-driver <driver> Pen tablet input driver.\n"); OS::get_singleton()->print(" --headless Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script.\n"); OS::get_singleton()->print("\n"); @@ -334,15 +333,15 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --resolution <W>x<H> Request window resolution.\n"); OS::get_singleton()->print(" --position <X>,<Y> Request window position.\n"); OS::get_singleton()->print(" --single-window Use a single window (no separate subwindows).\n"); - OS::get_singleton()->print(" --tablet-driver Pen tablet input driver.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Debug options:\n"); OS::get_singleton()->print(" -d, --debug Debug (local stdout debugger).\n"); OS::get_singleton()->print(" -b, --breakpoints Breakpoint list as source::line comma-separated pairs, no spaces (use %%20 instead).\n"); OS::get_singleton()->print(" --profiling Enable profiling in the script debugger.\n"); - OS::get_singleton()->print(" --vk-layers Enable Vulkan Validation layers for debugging.\n"); -#ifdef DEBUG_ENABLED + OS::get_singleton()->print(" --gpu-profile Show a GPU profile of the tasks that took the most time during frame rendering.\n"); + OS::get_singleton()->print(" --vk-layers Enable Vulkan validation layers for debugging.\n"); +#if DEBUG_ENABLED OS::get_singleton()->print(" --gpu-abort Abort on GPU errors (usually validation layer errors), may help see the problem if your system freezes.\n"); #endif OS::get_singleton()->print(" --remote-debug <uri> Remote debug (<protocol>://<host/IP>[:<port>], e.g. tcp://127.0.0.1:6007).\n"); @@ -356,7 +355,6 @@ void Main::print_help(const char *p_binary) { OS::get_singleton()->print(" --disable-crash-handler Disable crash handler when supported by the platform code.\n"); OS::get_singleton()->print(" --fixed-fps <fps> Force a fixed number of frames per second. This setting disables real-time synchronization.\n"); OS::get_singleton()->print(" --print-fps Print the frames per second to the stdout.\n"); - OS::get_singleton()->print(" --profile-gpu Show a simple profile of the tasks that took more time during frame rendering.\n"); OS::get_singleton()->print("\n"); OS::get_singleton()->print("Standalone tools:\n"); @@ -644,7 +642,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } else if (I->get() == "-v" || I->get() == "--verbose") { // verbose output OS::get_singleton()->_verbose_stdout = true; - } else if (I->get() == "--quiet") { // quieter output + } else if (I->get() == "-q" || I->get() == "--quiet") { // quieter output quiet_stdout = true; @@ -787,7 +785,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph Engine::singleton->gpu_idx = I->next()->get().to_int(); N = I->next()->next(); } else { - OS::get_singleton()->print("Missing gpu index argument, aborting.\n"); + OS::get_singleton()->print("Missing GPU index argument, aborting.\n"); goto error; } } else if (I->get() == "--vk-layers") { @@ -978,7 +976,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } else if (I->get() == "-u" || I->get() == "--upwards") { // scan folders upwards upwards = true; - } else if (I->get() == "-q" || I->get() == "--quit") { // Auto quit at the end of the first main loop iteration + } else if (I->get() == "--quit") { // Auto quit at the end of the first main loop iteration auto_quit = true; } else if (I->get().ends_with("project.godot")) { String path; @@ -2247,7 +2245,7 @@ bool Main::start() { bool embed_subwindows = GLOBAL_DEF("display/window/subwindows/embed_subwindows", true); if (OS::get_singleton()->is_single_window() || (!project_manager && !editor && embed_subwindows)) { - sml->get_root()->set_embed_subwindows_hint(true); + sml->get_root()->set_embedding_subwindows(true); } ResourceLoader::add_custom_loaders(); ResourceSaver::add_custom_savers(); @@ -2429,7 +2427,7 @@ bool Main::start() { "interface/editor/single_window_mode"); if (editor_embed_subwindows) { - sml->get_root()->set_embed_subwindows_hint(true); + sml->get_root()->set_embedding_subwindows(true); } } #endif diff --git a/misc/dist/shell/_godot.zsh-completion b/misc/dist/shell/_godot.zsh-completion index 8548b18cb0..98ab41ac58 100644 --- a/misc/dist/shell/_godot.zsh-completion +++ b/misc/dist/shell/_godot.zsh-completion @@ -30,10 +30,11 @@ _arguments \ '(-h --help)'{-h,--help}'[display the full help message]' \ '--version[display the version string]' \ '(-v --verbose)'{-v,--verbose}'[use verbose stdout mode]' \ - '--quiet[quiet mode, silences stdout messages (errors are still displayed)]' \ + '(-q --quiet)'{-q,--quiet}'[quiet mode, silences stdout messages (errors are still displayed)]' \ '(-e --editor)'{-e,--editor}'[start the editor instead of running the scene]' \ '(-p --project-manager)'{-p,--project-manager}'[start the project manager, even if a project is auto-detected]' \ - '(-q --quit)'{-q,--quit}'[quit after the first iteration]' \ + '--debug-server[start the editor debug server]:editor debugger listen address' \ + '--quit[quit after the first iteration]' \ '(-l --language)'{-l,--language}'[use a specific locale (<locale> being a two-letter code)]:two-letter locale code' \ "--path[path to a project (<directory> must contain a 'project.godot' file)]:path to directory with 'project.godot' file:_dirs" \ '(-u --upwards)'{-u,--upwards}'[scan folders upwards for project.godot file]' \ @@ -42,7 +43,12 @@ _arguments \ '--remote-fs[use a remote filesystem]:remote filesystem address' \ '--remote-fs-password[password for remote filesystem]:remote filesystem password' \ '--audio-driver[set the audio driver]:audio driver name' \ - "--video-driver[set the video driver]:video driver name:((Vulkan\:'Vulkan renderer' GLES2\:'OpenGL ES 2.0 renderer'))" \ + '--display-driver[set the display driver]:display driver name' \ + "--rendering-driver[set the rendering driver]:rendering driver name:((vulkan\:'Vulkan renderer' opengl3\:'OpenGL ES 3.0 renderer' dummy\:'Dummy renderer'))" \ + "--gpu-index[use a specific GPU (run with --verbose to get available device list)]:device index" \ + '--text-driver[set the text driver]:text driver name' \ + '--tablet-driver[set the pen tablet input driver]:tablet driver name' \ + '--headless[enable headless mode (--display-driver headless --audio-driver Dummy), useful for servers and with --script]' \ '(-f --fullscreen)'{-f,--fullscreen}'[request fullscreen mode]' \ '(-m --maximized)'{-m,--maximized}'[request a maximized window]' \ '(-w --windowed)'{-w,--windowed}'[request windowed mode]' \ @@ -50,9 +56,13 @@ _arguments \ '--resolution[request window resolution]:resolution in WxH format' \ '--position[request window position]:position in X,Y format' \ '--headless[enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script]' \ + '--single-window[use a single window (no separate subwindows)]' \ '(-d --debug)'{-d,--debug}'[debug (local stdout debugger)]' \ '(-b --breakpoints)'{-b,--breakpoints}'[specify the breakpoint list as source::line comma-separated pairs, no spaces (use %20 instead)]:breakpoint list' \ '--profiling[enable profiling in the script debugger]' \ + '--gpu-profile[show a GPU profile of the tasks that took the most time during frame rendering]' \ + '--vk-layers[enable Vulkan validation layers for debugging]' \ + '--gpu-abort[abort on GPU errors (usually validation layer errors)]' \ '--remote-debug[enable remote debugging]:remote debugger address' \ '--debug-collisions[show collision shapes when running the scene]' \ '--debug-navigation[show navigation polygons when running the scene]' \ @@ -64,10 +74,11 @@ _arguments \ '--print-fps[print the frames per second to the stdout]' \ '(-s, --script)'{-s,--script}'[run a script]:path to script:_files' \ '--check-only[only parse for errors and quit (use with --script)]' \ - '--export[export the project using the given preset and matching release template]:export preset name' \ - '--export-debug[same as --export, but using the debug template]:export preset name' \ - '--export-pack[same as --export, but only export the game pack for the given preset]:export preset name' \ - '--doctool[dump the engine API reference to the given path in XML format, merging if existing files are found]:path to base Godot build directory:_dirs' \ + '--export[export the project using the given preset and matching release template]:export preset name then path' \ + '--export-debug[same as --export, but using the debug template]:export preset name then path' \ + '--export-pack[same as --export, but only export the game pack for the given preset]:export preset name then path' \ + '--doctool[dump the engine API reference to the given path in XML format, merging if existing files are found]:path to base Godot build directory (optional):_dirs' \ '--no-docbase[disallow dumping the base types (used with --doctool)]' \ '--build-solutions[build the scripting solutions (e.g. for C# projects)]' \ - '--test[run a unit test]:unit test name' + '--dump-extension-api[generate JSON dump of the Godot API for GDExtension bindings named "extension_api.json" in the current folder]' \ + '--test[run all unit tests; run with "--test --help" for more information]' diff --git a/misc/dist/shell/godot.bash-completion b/misc/dist/shell/godot.bash-completion index 56bf23a268..5784e15c6e 100644 --- a/misc/dist/shell/godot.bash-completion +++ b/misc/dist/shell/godot.bash-completion @@ -36,6 +36,7 @@ _complete_godot_options() { --quiet --editor --project-manager +--debug-server --quit --language --path @@ -45,7 +46,12 @@ _complete_godot_options() { --remote-fs --remote-fs-password --audio-driver ---video-driver +--display-driver +--rendering-driver +--gpu-index +--text-driver +--tablet-driver +--headless --fullscreen --maximized --windowed @@ -53,9 +59,13 @@ _complete_godot_options() { --resolution --position --headless +--single-window --debug --breakpoints --profiling +--gpu-profile +--vk-layers +--gpu-abort --remote-debug --debug-collisions --debug-navigation @@ -73,6 +83,7 @@ _complete_godot_options() { --doctool --no-docbase --build-solutions +--dump-extension-api --test " -- "$1")) } @@ -98,10 +109,10 @@ _complete_godot_bash() { local IFS=$' \n\t' # shellcheck disable=SC2207 COMPREPLY=($(compgen -W "unsafe safe separate" -- "$cur")) - elif [[ $prev == "--video-driver" ]]; then + elif [[ $prev == "--rendering-driver" ]]; then local IFS=$' \n\t' # shellcheck disable=SC2207 - COMPREPLY=($(compgen -W "Vulkan GLES2" -- "$cur")) + COMPREPLY=($(compgen -W "vulkan opengl3 dummy" -- "$cur")) elif [[ $prev == "--path" || $prev == "--doctool" ]]; then local IFS=$'\n\t' # shellcheck disable=SC2207 diff --git a/misc/dist/shell/godot.fish b/misc/dist/shell/godot.fish index 6aa3f38f1f..880851dd23 100644 --- a/misc/dist/shell/godot.fish +++ b/misc/dist/shell/godot.fish @@ -23,10 +23,11 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -function godot_video_driver_args +function godot_rendering_driver_args # Use a function instead of a fixed string to customize the argument descriptions. - echo -e "Vulkan\tVulkan renderer" - echo -e "GLES2\tOpenGL ES 2.0 renderer" + echo -e "vulkan\tVulkan renderer" + echo -e "opengl3\tOpenGL ES 3.0 renderer" + echo -e "dummy\tDummy renderer" end # Erase existing completions for Godot. @@ -36,12 +37,13 @@ complete -c godot -e complete -c godot -s h -l help -d "Display the full help message" complete -c godot -l version -d "Display the version string" complete -c godot -s v -l verbose -d "Use verbose stdout mode" -complete -c godot -l quiet -d "Quiet mode, silences stdout messages (errors are still displayed)" +complete -c godot -s q -l quiet -d "Quiet mode, silences stdout messages (errors are still displayed)" # Run options: complete -c godot -s e -l editor -d "Start the editor instead of running the scene" complete -c godot -s p -l project-manager -d "Start the project manager, even if a project is auto-detected" -complete -c godot -s q -l quit -d "Quit after the first iteration" +complete -c godot -l debug-server -d "Start the editor debug server (<protocol>://<host/IP>[:<port>] address)" -x +complete -c godot -l quit -d "Quit after the first iteration" complete -c godot -s l -l language -d "Use a specific locale (<locale> being a two-letter code)" -x complete -c godot -l path -d "Path to a project (<directory> must contain a 'project.godot' file)" -r complete -c godot -s u -l upwards -d "Scan folders upwards for project.godot file" @@ -50,7 +52,12 @@ complete -c godot -l render-thread -d "Set the render thread mode" -x -a "unsafe complete -c godot -l remote-fs -d "Use a remote filesystem (<host/IP>[:<port>] address)" -x complete -c godot -l remote-fs-password -d "Password for remote filesystem" -x complete -c godot -l audio-driver -d "Set the audio driver" -x -complete -c godot -l video-driver -d "Set the video driver" -x -a "(godot_video_driver_args)" +complete -c godot -l display-driver -d "Set the display driver" -x +complete -c godot -l rendering-driver -d "Set the rendering driver" -x -a "(godot_rendering_driver_args)" +complete -c godot -l gpu-index -d "Use a specific GPU (run with --verbose to get available device list)" -x +complete -c godot -l text-driver -d "Set the text driver" -x +complete -c godot -l tablet-driver -d "Set the pen tablet input driver" -x +complete -c godot -l headless -d "Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script" # Display options: complete -c godot -s f -l fullscreen -d "Request fullscreen mode" @@ -60,11 +67,15 @@ complete -c godot -s t -l always-on-top -d "Request an always-on-top window" complete -c godot -l resolution -d "Request window resolution" -x complete -c godot -l position -d "Request window position" -x complete -c godot -l headless -d "Enable headless mode (--display-driver headless --audio-driver Dummy). Useful for servers and with --script" +complete -c godot -l single-window -d "Use a single window (no separate subwindows)" # Debug options: complete -c godot -s d -l debug -d "Debug (local stdout debugger)" complete -c godot -s b -l breakpoints -d "Specify the breakpoint list as source::line comma-separated pairs, no spaces (use %20 instead)" -x complete -c godot -l profiling -d "Enable profiling in the script debugger" +complete -c godot -l gpu-profile -d "Show a GPU profile of the tasks that took the most time during frame rendering" +complete -c godot -l vk-layers -d "Enable Vulkan validation layers for debugging" +complete -c godot -l gpu-abort -d "Abort on GPU errors (usually validation layer errors)" complete -c godot -l remote-debug -d "Enable remote debugging" complete -c godot -l debug-collisions -d "Show collision shapes when running the scene" complete -c godot -l debug-navigation -d "Show navigation polygons when running the scene" @@ -84,4 +95,5 @@ complete -c godot -l export-pack -d "Same as --export, but only export the game complete -c godot -l doctool -d "Dump the engine API reference to the given path in XML format, merging if existing files are found" -r complete -c godot -l no-docbase -d "Disallow dumping the base types (used with --doctool)" complete -c godot -l build-solutions -d "Build the scripting solutions (e.g. for C# projects)" -complete -c godot -l test -d "Run a unit test" -x +complete -c godot -l dump-extension-api -d "Generate JSON dump of the Godot API for GDExtension bindings named 'extension_api.json' in the current folder" +complete -c godot -l test -d "Run all unit tests; run with '--test --help' for more information" -x diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index 96b83bf25a..79ef2de929 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -78,7 +78,7 @@ void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_strin return; } float fw, fh; - picture->viewbox(nullptr, nullptr, &fw, &fh); + picture->size(&fw, &fh); uint32_t width = MIN(fw * p_scale, 16 * 1024); uint32_t height = MIN(fh * p_scale, 16 * 1024); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 72a87e5503..7fd9cd42ed 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -2326,6 +2326,20 @@ void TextServerAdvanced::font_remove_glyph(RID p_font_rid, const Vector2i &p_siz fd->cache[size]->glyph_map.erase(p_glyph); } +float TextServerAdvanced::_get_extra_advance(RID p_font_rid, int p_font_size) const { + const FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, 0.0); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size(fd, p_font_size); + + if (fd->embolden != 0.0) { + return fd->embolden * float(size.x) / 64.0; + } else { + return 0.0; + } +} + Vector2 TextServerAdvanced::font_get_glyph_advance(RID p_font_rid, int p_size, int32_t p_glyph) const { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Vector2()); @@ -2340,12 +2354,17 @@ Vector2 TextServerAdvanced::font_get_glyph_advance(RID p_font_rid, int p_size, i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + Vector2 ea; + if (fd->embolden != 0.0) { + ea.x = fd->embolden * float(size.x) / 64.0; + } + if (fd->msdf) { - return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size; + return (gl[p_glyph].advance + ea) * (float)p_size / (float)fd->msdf_source_size; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - return gl[p_glyph].advance.round(); + return (gl[p_glyph].advance + ea).round(); } else { - return gl[p_glyph].advance; + return gl[p_glyph].advance + ea; } } @@ -4471,9 +4490,9 @@ Glyph TextServerAdvanced::_shape_single_glyph(ShapedTextDataAdvanced *p_sd, char float scale = font_get_scale(p_font, p_font_size); if (p_sd->orientation == ORIENTATION_HORIZONTAL) { if (subpos) { - gl.advance = glyph_pos[0].x_advance / (64.0 / scale); + gl.advance = glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size); } else { - gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale)); + gl.advance = Math::round(glyph_pos[0].x_advance / (64.0 / scale) + _get_extra_advance(p_font, p_font_size)); } } else { gl.advance = -Math::round(glyph_pos[0].y_advance / (64.0 / scale)); @@ -4550,6 +4569,7 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star float scale = font_get_scale(f, fs); float sp_sp = font_get_spacing(f, fs, SPACING_SPACE); float sp_gl = font_get_spacing(f, fs, SPACING_GLYPH); + float 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); @@ -4628,9 +4648,9 @@ void TextServerAdvanced::_shape_run(ShapedTextDataAdvanced *p_sd, int32_t p_star if (gl.index != 0) { if (p_sd->orientation == ORIENTATION_HORIZONTAL) { if (subpos) { - gl.advance = glyph_pos[i].x_advance / (64.0 / scale); + gl.advance = glyph_pos[i].x_advance / (64.0 / scale) + ea; } else { - gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale)); + gl.advance = Math::round(glyph_pos[i].x_advance / (64.0 / scale) + ea); } } else { gl.advance = -Math::round(glyph_pos[i].y_advance / (64.0 / scale)); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index f63ff645bf..e5958fc162 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -242,6 +242,8 @@ class TextServerAdvanced : public TextServer { } } + _FORCE_INLINE_ float _get_extra_advance(RID p_font_rid, int p_font_size) const; + // Shaped text cache data. struct ShapedTextDataAdvanced : public ShapedTextData { diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 5a4b20b2ef..0d7a9d0db8 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -1513,12 +1513,17 @@ Vector2 TextServerFallback::font_get_glyph_advance(RID p_font_rid, int p_size, i const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + Vector2 ea; + if (fd->embolden != 0.0) { + ea.x = fd->embolden * float(size.x) / 64.0; + } + if (fd->msdf) { - return gl[p_glyph].advance * (float)p_size / (float)fd->msdf_source_size; + return (gl[p_glyph].advance + ea) * (float)p_size / (float)fd->msdf_source_size; } else if ((fd->subpixel_positioning == SUBPIXEL_POSITIONING_DISABLED) || (fd->subpixel_positioning == SUBPIXEL_POSITIONING_AUTO && size.x > SUBPIXEL_POSITIONING_ONE_HALF_MAX_SIZE)) { - return gl[p_glyph].advance.round(); + return (gl[p_glyph].advance + ea).round(); } else { - return gl[p_glyph].advance; + return gl[p_glyph].advance + ea; } } diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 27b4a2018f..e1ab2d1c83 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1917,16 +1917,14 @@ void DisplayServerWindows::set_icon(const Ref<Image> &p_icon) { void DisplayServerWindows::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ #if defined(VULKAN_ENABLED) - // TODO disabling for now - //context_vulkan->set_vsync_mode(p_window, p_vsync_mode); + context_vulkan->set_vsync_mode(p_window, p_vsync_mode); #endif } DisplayServer::VSyncMode DisplayServerWindows::window_get_vsync_mode(WindowID p_window) const { _THREAD_SAFE_METHOD_ #if defined(VULKAN_ENABLED) - //TODO disabling for now - //return context_vulkan->get_vsync_mode(p_window); + return context_vulkan->get_vsync_mode(p_window); #endif return DisplayServer::VSYNC_ENABLED; } diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 390e6685b1..efde8d8a2b 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -79,6 +79,7 @@ void Camera2D::set_zoom(const Vector2 &p_zoom) { ERR_FAIL_COND_MSG(Math::is_zero_approx(p_zoom.x) || Math::is_zero_approx(p_zoom.y), "Zoom level must be different from 0 (can be negative)."); zoom = p_zoom; + zoom_scale = Vector2(1, 1) / zoom; Point2 old_smoothed_camera_pos = smoothed_camera_pos; _update_scroll(); smoothed_camera_pos = old_smoothed_camera_pos; @@ -103,8 +104,8 @@ Transform2D Camera2D::get_camera_transform() { if (!first) { if (anchor_mode == ANCHOR_MODE_DRAG_CENTER) { if (drag_horizontal_enabled && !Engine::get_singleton()->is_editor_hint() && !drag_horizontal_offset_changed) { - camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom.x * drag_margin[SIDE_LEFT])); - camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom.x * drag_margin[SIDE_RIGHT])); + camera_pos.x = MIN(camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * zoom_scale.x * drag_margin[SIDE_LEFT])); + camera_pos.x = MAX(camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * zoom_scale.x * drag_margin[SIDE_RIGHT])); } else { if (drag_horizontal_offset < 0) { camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[SIDE_RIGHT] * drag_horizontal_offset; @@ -116,8 +117,8 @@ Transform2D Camera2D::get_camera_transform() { } if (drag_vertical_enabled && !Engine::get_singleton()->is_editor_hint() && !drag_vertical_offset_changed) { - camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom.y * drag_margin[SIDE_TOP])); - camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom.y * drag_margin[SIDE_BOTTOM])); + camera_pos.y = MIN(camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * zoom_scale.y * drag_margin[SIDE_TOP])); + camera_pos.y = MAX(camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * zoom_scale.y * drag_margin[SIDE_BOTTOM])); } else { if (drag_vertical_offset < 0) { @@ -133,8 +134,8 @@ Transform2D Camera2D::get_camera_transform() { camera_pos = new_camera_pos; } - Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2()); - Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom); + Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2()); + Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom_scale); if (limit_smoothing_enabled) { if (screen_rect.position.x < limit[SIDE_LEFT]) { @@ -168,14 +169,14 @@ Transform2D Camera2D::get_camera_transform() { first = false; } - Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2()); + Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom_scale) : Point2()); real_t angle = get_global_rotation(); if (rotating) { screen_offset = screen_offset.rotated(angle); } - Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom); + Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom_scale); if (!smoothing_enabled || !limit_smoothing_enabled) { if (screen_rect.position.x < limit[SIDE_LEFT]) { @@ -202,7 +203,7 @@ Transform2D Camera2D::get_camera_transform() { camera_screen_center = screen_rect.get_center(); Transform2D xform; - xform.scale_basis(zoom); + xform.scale_basis(zoom_scale); if (rotating) { xform.set_rotation(angle); } diff --git a/scene/2d/camera_2d.h b/scene/2d/camera_2d.h index 662bee3612..294a6fcb80 100644 --- a/scene/2d/camera_2d.h +++ b/scene/2d/camera_2d.h @@ -61,6 +61,7 @@ protected: RID canvas; Vector2 offset; Vector2 zoom = Vector2(1, 1); + Vector2 zoom_scale = Vector2(1, 1); AnchorMode anchor_mode = ANCHOR_MODE_DRAG_CENTER; bool rotating = false; bool current = false; diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp index 2716bb2e25..8cbcc9acf6 100644 --- a/scene/2d/line_2d.cpp +++ b/scene/2d/line_2d.cpp @@ -265,15 +265,15 @@ bool Line2D::get_antialiased() const { } void Line2D::_draw() { - if (_points.size() <= 1 || _width == 0.f) { + int len = _points.size(); + if (len <= 1 || _width == 0.f) { return; } // TODO Is this really needed? // Copy points for faster access Vector<Vector2> points; - points.resize(_points.size()); - int len = points.size(); + points.resize(len); { const Vector2 *points_read = _points.ptr(); for (int i = 0; i < len; ++i) { diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index 9d26543243..dd88bda304 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -244,10 +244,9 @@ Point2 Node2D::get_global_position() const { } void Node2D::set_global_position(const Point2 &p_pos) { - Transform2D inv; CanvasItem *pi = get_parent_item(); if (pi) { - inv = pi->get_global_transform().affine_inverse(); + Transform2D inv = pi->get_global_transform().affine_inverse(); set_position(inv.xform(p_pos)); } else { set_position(p_pos); diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index 1fe4adb4db..f9986c2f30 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -295,14 +295,14 @@ void Polygon2D::_notification(int p_what) { } Vector<Color> colors; + colors.resize(len); + if (vertex_colors.size() == points.size()) { - colors.resize(len); const Color *color_r = vertex_colors.ptr(); for (int i = 0; i < len; i++) { colors.write[i] = color_r[i]; } } else { - colors.resize(len); for (int i = 0; i < len; i++) { colors.write[i] = color; } diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 724714b93b..29a0681f9c 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -293,7 +293,7 @@ void Button::_notification(int p_what) { int text_clip = size.width - style->get_minimum_size().width - icon_ofs.width; text_buf->set_width(clip_text ? text_clip : -1); - int text_width = clip_text ? MIN(text_clip, text_buf->get_size().x) : text_buf->get_size().x; + int text_width = MAX(1, clip_text ? MIN(text_clip, text_buf->get_size().x) : text_buf->get_size().x); if (_internal_margin[SIDE_LEFT] > 0) { text_clip -= _internal_margin[SIDE_LEFT] + get_theme_constant(SNAME("hseparation")); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index d8659b1f18..d2d1b5e9b7 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -3224,6 +3224,7 @@ void Control::_bind_methods() { ClassDB::bind_method(D_METHOD("get_custom_minimum_size"), &Control::get_custom_minimum_size); ClassDB::bind_method(D_METHOD("get_parent_area_size"), &Control::get_parent_area_size); ClassDB::bind_method(D_METHOD("get_global_position"), &Control::get_global_position); + ClassDB::bind_method(D_METHOD("get_screen_position"), &Control::get_screen_position); ClassDB::bind_method(D_METHOD("get_rect"), &Control::get_rect); ClassDB::bind_method(D_METHOD("get_global_rect"), &Control::get_global_rect); ClassDB::bind_method(D_METHOD("set_focus_mode", "mode"), &Control::set_focus_mode); diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index bad7be7d42..0a36176c98 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -902,9 +902,10 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o for (int i = 0; i < gl_size; i++) { Item *it = _get_item_at_pos(it_from, it_to, glyphs[i].start); int size = _find_outline_size(it, p_outline_size); - Color font_color = _find_outline_color(it, p_outline_color); + Color font_color = _find_color(it, p_base_color); + Color font_outline_color = _find_outline_color(it, p_outline_color); Color font_shadow_color = p_font_shadow_color; - if ((size <= 0 || font_color.a == 0) && (font_shadow_color.a == 0)) { + if ((size <= 0 || font_outline_color.a == 0) && (font_shadow_color.a == 0)) { gloff.x += glyphs[i].advance; continue; } @@ -950,11 +951,11 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o faded_visibility -= (float)(glyphs[i].start - fade->starting_index) / (float)fade->length; faded_visibility = faded_visibility < 0.0f ? 0.0f : faded_visibility; } - font_color.a = faded_visibility; + font_outline_color.a = faded_visibility; font_shadow_color.a = faded_visibility; } - bool visible = (font_color.a != 0) || (font_shadow_color.a != 0); + bool visible = (font_outline_color.a != 0) || (font_shadow_color.a != 0); for (int j = 0; j < fx_stack.size(); j++) { ItemFX *item_fx = fx_stack[j]; @@ -1024,18 +1025,20 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o } // Draw glyph outlines. + const Color modulated_outline_color = font_outline_color * Color(1, 1, 1, font_color.a); + const Color modulated_shadow_color = font_shadow_color * Color(1, 1, 1, font_color.a); for (int j = 0; j < glyphs[i].repeat; j++) { if (visible) { bool skip = (trim_chars && l.char_offset + glyphs[i].end > visible_characters) || (trim_glyphs_ltr && (processed_glyphs_ol >= visible_glyphs)) || (trim_glyphs_rtl && (processed_glyphs_ol < total_glyphs - visible_glyphs)); if (!skip && frid != RID()) { - if (font_shadow_color.a > 0) { - TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, font_shadow_color); + if (modulated_shadow_color.a > 0) { + TS->font_draw_glyph(frid, ci, glyphs[i].font_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color); } - if (font_shadow_color.a > 0 && p_shadow_outline_size > 0) { - TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, p_shadow_outline_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, font_shadow_color); + if (modulated_shadow_color.a > 0 && p_shadow_outline_size > 0) { + TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, p_shadow_outline_size, p_ofs + fx_offset + gloff + p_shadow_ofs, gl, modulated_shadow_color); } - if (font_color.a != 0.0 && size > 0) { - TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, font_color); + if (modulated_outline_color.a != 0.0 && size > 0) { + TS->font_draw_glyph_outline(frid, ci, glyphs[i].font_size, size, p_ofs + fx_offset + gloff, gl, modulated_outline_color); } } processed_glyphs_ol++; diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp index d2f5b52dbf..1d263ba858 100644 --- a/scene/main/canvas_item.cpp +++ b/scene/main/canvas_item.cpp @@ -866,7 +866,6 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("_set_on_top", "on_top"), &CanvasItem::_set_on_top); ClassDB::bind_method(D_METHOD("_is_on_top"), &CanvasItem::_is_on_top); - //ClassDB::bind_method(D_METHOD("get_transform"),&CanvasItem::get_transform); ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width"), &CanvasItem::draw_line, DEFVAL(1.0)); ClassDB::bind_method(D_METHOD("draw_polyline", "points", "color", "width", "antialiased"), &CanvasItem::draw_polyline, DEFVAL(1.0), DEFVAL(false)); @@ -899,6 +898,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("get_viewport_transform"), &CanvasItem::get_viewport_transform); ClassDB::bind_method(D_METHOD("get_viewport_rect"), &CanvasItem::get_viewport_rect); ClassDB::bind_method(D_METHOD("get_canvas_transform"), &CanvasItem::get_canvas_transform); + ClassDB::bind_method(D_METHOD("get_screen_transform"), &CanvasItem::get_screen_transform); ClassDB::bind_method(D_METHOD("get_local_mouse_position"), &CanvasItem::get_local_mouse_position); ClassDB::bind_method(D_METHOD("get_global_mouse_position"), &CanvasItem::get_global_mouse_position); ClassDB::bind_method(D_METHOD("get_canvas"), &CanvasItem::get_canvas); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index de6aa2b139..ec33e5752e 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -2033,6 +2033,17 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { } } +void Viewport::_gui_cleanup_internal_state(Ref<InputEvent> p_event) { + ERR_FAIL_COND(p_event.is_null()); + + Ref<InputEventMouseButton> mb = p_event; + if (mb.is_valid()) { + if (!mb->is_pressed()) { + gui.mouse_focus_mask &= ~mouse_button_to_mask(mb->get_button_index()); // Remove from mask. + } + } +} + List<Control *>::Element *Viewport::_gui_add_root_control(Control *p_control) { gui.roots_order_dirty = true; return gui.roots.push_back(p_control); @@ -2695,6 +2706,9 @@ void Viewport::push_input(const Ref<InputEvent> &p_event, bool p_local_coords) { if (!is_input_handled()) { _gui_input_event(ev); + } else { + // Cleanup internal GUI state after accepting event during _input(). + _gui_cleanup_internal_state(ev); } event_count++; @@ -2768,6 +2782,14 @@ Vector2 Viewport::get_camera_rect_size() const { } void Viewport::set_disable_input(bool p_disable) { + if (p_disable == disable_input) { + return; + } + if (p_disable) { + _drop_mouse_focus(); + _drop_mouse_over(); + _gui_cancel_tooltip(); + } disable_input = p_disable; } @@ -3040,14 +3062,10 @@ Viewport *Viewport::get_parent_viewport() const { return get_parent()->get_viewport(); } -void Viewport::set_embed_subwindows_hint(bool p_embed) { +void Viewport::set_embedding_subwindows(bool p_embed) { gui.embed_subwindows_hint = p_embed; } -bool Viewport::get_embed_subwindows_hint() const { - return gui.embed_subwindows_hint; -} - bool Viewport::is_embedding_subwindows() const { return gui.embed_subwindows_hint; } @@ -3638,8 +3656,7 @@ void Viewport::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_filter", "mode"), &Viewport::set_default_canvas_item_texture_filter); ClassDB::bind_method(D_METHOD("get_default_canvas_item_texture_filter"), &Viewport::get_default_canvas_item_texture_filter); - ClassDB::bind_method(D_METHOD("set_embed_subwindows_hint", "enable"), &Viewport::set_embed_subwindows_hint); - ClassDB::bind_method(D_METHOD("get_embed_subwindows_hint"), &Viewport::get_embed_subwindows_hint); + ClassDB::bind_method(D_METHOD("set_embedding_subwindows", "enable"), &Viewport::set_embedding_subwindows); ClassDB::bind_method(D_METHOD("is_embedding_subwindows"), &Viewport::is_embedding_subwindows); ClassDB::bind_method(D_METHOD("set_default_canvas_item_texture_repeat", "mode"), &Viewport::set_default_canvas_item_texture_repeat); @@ -3721,7 +3738,7 @@ void Viewport::_bind_methods() { ADD_GROUP("GUI", "gui_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_disable_input"), "set_disable_input", "is_input_disabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_snap_controls_to_pixels"), "set_snap_controls_to_pixels", "is_snap_controls_to_pixels_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_embed_subwindows"), "set_embed_subwindows_hint", "get_embed_subwindows_hint"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "gui_embed_subwindows"), "set_embedding_subwindows", "is_embedding_subwindows"); 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"); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index 93e42f1838..e4912f31c5 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -388,6 +388,7 @@ private: Control *_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform); void _gui_input_event(Ref<InputEvent> p_event); + void _gui_cleanup_internal_state(Ref<InputEvent> p_event); _FORCE_INLINE_ Transform2D _get_input_pre_xform() const; @@ -600,8 +601,7 @@ public: virtual DisplayServer::WindowID get_window_id() const = 0; - void set_embed_subwindows_hint(bool p_embed); - bool get_embed_subwindows_hint() const; + void set_embedding_subwindows(bool p_embed); bool is_embedding_subwindows() const; Viewport *get_parent_viewport() const; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 1c9b08b6d3..bd1c2b5758 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -1,9 +1,9 @@ // Functions related to lighting float D_GGX(float cos_theta_m, float alpha) { - float alpha2 = alpha * alpha; - float d = 1.0 + (alpha2 - 1.0) * cos_theta_m * cos_theta_m; - return alpha2 / (M_PI * d * d); + float a = cos_theta_m * alpha; + float k = alpha / (1.0 - cos_theta_m * cos_theta_m + a * a); + return k * k * (1.0 / M_PI); } // From Earl Hammon, Jr. "PBR Diffuse Lighting for GGX+Smith Microsurfaces" https://www.gdcvault.com/play/1024478/PBR-Diffuse-Lighting-for-GGX diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp index d34fd572ad..a6992014e8 100644 --- a/servers/rendering_server.cpp +++ b/servers/rendering_server.cpp @@ -2580,6 +2580,7 @@ void RenderingServer::_bind_methods() { ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture"), &RenderingServer::canvas_item_add_particles); ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &RenderingServer::canvas_item_add_set_transform); ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &RenderingServer::canvas_item_add_clip_ignore); + ClassDB::bind_method(D_METHOD("canvas_item_add_animation_slice", "item", "animation_length", "slice_begin", "slice_end", "offset"), &RenderingServer::canvas_item_add_animation_slice, DEFVAL(0.0)); ClassDB::bind_method(D_METHOD("canvas_item_set_sort_children_by_y", "item", "enabled"), &RenderingServer::canvas_item_set_sort_children_by_y); ClassDB::bind_method(D_METHOD("canvas_item_set_z_index", "item", "z_index"), &RenderingServer::canvas_item_set_z_index); ClassDB::bind_method(D_METHOD("canvas_item_set_z_as_relative_to_parent", "item", "enabled"), &RenderingServer::canvas_item_set_z_as_relative_to_parent); diff --git a/servers/text_server.cpp b/servers/text_server.cpp index d188076607..aaba79c049 100644 --- a/servers/text_server.cpp +++ b/servers/text_server.cpp @@ -1267,11 +1267,11 @@ void TextServer::shaped_text_draw(RID p_shaped, RID p_canvas, const Vector2 &p_p if (p_clip_r > 0) { // Clip right / bottom. if (orientation == ORIENTATION_HORIZONTAL) { - if (ofs.x - p_pos.x > p_clip_r) { + if (ofs.x - p_pos.x + glyphs[i].advance > p_clip_r) { return; } } else { - if (ofs.y - p_pos.y > p_clip_r) { + if (ofs.y - p_pos.y + glyphs[i].advance > p_clip_r) { return; } } @@ -1362,11 +1362,11 @@ void TextServer::shaped_text_draw_outline(RID p_shaped, RID p_canvas, const Vect if (p_clip_r > 0) { // Clip right / bottom. if (orientation == ORIENTATION_HORIZONTAL) { - if (ofs.x - p_pos.x > p_clip_r) { + if (ofs.x - p_pos.x + glyphs[i].advance > p_clip_r) { return; } } else { - if (ofs.y - p_pos.y > p_clip_r) { + if (ofs.y - p_pos.y + glyphs[i].advance > p_clip_r) { return; } } |