diff --git a/doc/classes/SVGTexture.xml b/doc/classes/SVGTexture.xml index 2c738e08697..3133d58e39b 100644 --- a/doc/classes/SVGTexture.xml +++ b/doc/classes/SVGTexture.xml @@ -4,7 +4,7 @@ A scalable [Texture2D] based on an SVG image. - A scalable [Texture2D] based on an SVG image. [SVGTexture]s are automatically rescaled to match font oversampling. + A scalable [Texture2D] based on an SVG image. [SVGTexture]s are automatically re-rasterized to match font oversampling. @@ -29,10 +29,10 @@ - SVG texture scale. + SVG texture scale. [code]1.0[/code] is the original SVG size. Higher values result in a larger image. - If sets, remaps SVG texture colors according to [Color]-[Color] map. + If set, remaps SVG texture colors according to [Color]-[Color] map. diff --git a/editor/themes/editor_icons.cpp b/editor/themes/editor_icons.cpp index a415a9191e1..4b58c9cd361 100644 --- a/editor/themes/editor_icons.cpp +++ b/editor/themes/editor_icons.cpp @@ -35,6 +35,7 @@ #include "editor/themes/editor_icons.gen.h" #include "editor/themes/editor_scale.h" #include "scene/resources/image_texture.h" +#include "scene/resources/svg_texture.h" #include "modules/svg/image_loader_svg.h" @@ -47,20 +48,8 @@ void editor_configure_icons(bool p_dark_theme) { } // See also `generate_icon()` in `scene/theme/default_theme.cpp`. -Ref editor_generate_icon(int p_index, float p_scale, float p_saturation, const HashMap &p_convert_colors = HashMap()) { - Ref img = memnew(Image); - - // Upsample icon generation only if the editor scale isn't an integer multiplier. - // Generating upsampled icons is slower, and the benefit is hardly visible - // with integer editor scales. - const bool upsample = !Math::is_equal_approx(Math::round(p_scale), p_scale); - Error err = ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, upsample, p_convert_colors); - ERR_FAIL_COND_V_MSG(err != OK, Ref(), "Failed generating icon, unsupported or invalid SVG data in editor theme."); - if (p_saturation != 1.0) { - img->adjust_bcs(1.0, 1.0, p_saturation); - } - - return ImageTexture::create_from_image(img); +Ref editor_generate_icon(int p_index, float p_scale, float p_saturation, const Dictionary &p_convert_colors = Dictionary()) { + return SVGTexture::create_from_string(editor_icons_sources[p_index], p_scale, p_saturation, p_convert_colors); } float get_gizmo_handle_scale(const String &p_gizmo_handle_name, float p_gizmo_handle_scale) { @@ -94,8 +83,8 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p // And then some icons are completely excluded from the conversion. // Standard color conversion map. - HashMap color_conversion_map_light; - HashMap color_conversion_map_dark; + Dictionary color_conversion_map_light; + Dictionary color_conversion_map_dark; // Icons by default are set up for the dark theme, so if the theme is light, // we apply the dark-to-light color conversion map. for (KeyValue &E : EditorColorMap::get_color_conversion_map()) { @@ -112,7 +101,7 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p color_conversion_map_light[Color::html("#5fff97")] = success_color; color_conversion_map_light[Color::html("#ffdd65")] = warning_color; - HashMap color_conversion_map = p_dark_theme ? color_conversion_map_dark : color_conversion_map_light; + Dictionary color_conversion_map = p_dark_theme ? color_conversion_map_dark : color_conversion_map_light; // The names of the icons used in native menus. HashSet native_menu_icons; @@ -138,7 +127,7 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p // Accent color conversion map. // It is used on some icons (checkbox, radio, toggle, etc.), regardless of the dark // or light mode. - HashMap accent_color_map; + Dictionary accent_color_map; HashSet accent_color_icons; const Color accent_color = p_theme->get_color(SNAME("accent_color"), EditorStringName(Editor)); @@ -164,14 +153,14 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p saturation = 1.0; } - Ref icon_dark = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_dark); - Ref icon_light = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_light); + Ref icon_dark = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_dark); + Ref icon_light = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), saturation, color_conversion_map_light); p_theme->set_icon(editor_icon_name + "Dark", EditorStringName(EditorIcons), icon_dark); p_theme->set_icon(editor_icon_name + "Light", EditorStringName(EditorIcons), icon_light); p_theme->set_icon(editor_icon_name, EditorStringName(EditorIcons), p_dark_theme ? icon_dark : icon_light); } else { - Ref icon; + Ref icon; if (accent_color_icons.has(editor_icon_name)) { icon = editor_generate_icon(i, get_gizmo_handle_scale(editor_icon_name, p_gizmo_handle_scale), 1.0, accent_color_map); } else { @@ -198,7 +187,7 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p const float scale = (float)p_thumb_size / 64.0 * EDSCALE; for (int i = 0; i < editor_bg_thumbs_count; i++) { const int index = editor_bg_thumbs_indices[i]; - Ref icon; + Ref icon; if (accent_color_icons.has(editor_icons_names[index])) { icon = editor_generate_icon(index, scale, 1.0, accent_color_map); @@ -221,7 +210,7 @@ void editor_register_icons(const Ref &p_theme, bool p_dark_theme, float p const float scale = (float)p_thumb_size / 32.0 * EDSCALE; for (int i = 0; i < editor_md_thumbs_count; i++) { const int index = editor_md_thumbs_indices[i]; - Ref icon; + Ref icon; if (accent_color_icons.has(editor_icons_names[index])) { icon = editor_generate_icon(index, scale, 1.0, accent_color_map); diff --git a/editor/themes/editor_theme_manager.cpp b/editor/themes/editor_theme_manager.cpp index 5cf28870a85..b7472a93a08 100644 --- a/editor/themes/editor_theme_manager.cpp +++ b/editor/themes/editor_theme_manager.cpp @@ -44,6 +44,7 @@ #include "scene/resources/style_box_flat.h" #include "scene/resources/style_box_line.h" #include "scene/resources/style_box_texture.h" +#include "scene/resources/svg_texture.h" #include "scene/resources/texture.h" // Theme configuration. @@ -1724,7 +1725,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref &p_the p_theme->set_constant("port_h_offset", "GraphNode", 1); p_theme->set_constant("separation", "GraphNode", 1 * EDSCALE); - Ref port_icon = p_theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons)); + Ref port_icon = p_theme->get_icon(SNAME("GuiGraphNodePort"), EditorStringName(EditorIcons)); // The true size is 24x24 This is necessary for sharp port icons at high zoom levels in GraphEdit (up to ~200%). port_icon->set_size_override(Size2(12, 12)); p_theme->set_icon("port", "GraphNode", port_icon); diff --git a/scene/resources/svg_texture.cpp b/scene/resources/svg_texture.cpp index 9f88c0b6ff1..3e3ce5994c1 100644 --- a/scene/resources/svg_texture.cpp +++ b/scene/resources/svg_texture.cpp @@ -159,7 +159,7 @@ void SVGTexture::_remove_scale(double p_scale) { RID SVGTexture::_ensure_scale(double p_scale) const { if (Math::is_equal_approx(p_scale, 1.0)) { - if (!base_texture.is_valid()) { + if (base_texture.is_null()) { base_texture = _load_at_scale(p_scale, true); } return base_texture; @@ -180,7 +180,8 @@ RID SVGTexture::_ensure_scale(double p_scale) const { } RID SVGTexture::_load_at_scale(double p_scale, bool p_set_size) const { - Ref img = memnew(Image); + Ref img; + img.instantiate(); #ifdef MODULE_SVG_ENABLED const bool upsample = !Math::is_equal_approx(Math::round(p_scale * base_scale), p_scale * base_scale); @@ -300,7 +301,7 @@ void SVGTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const } bool SVGTexture::is_pixel_opaque(int p_x, int p_y) const { - if (!alpha_cache.is_valid()) { + if (alpha_cache.is_null()) { Ref img = get_image(); if (img.is_valid()) { alpha_cache.instantiate(); @@ -318,8 +319,8 @@ bool SVGTexture::is_pixel_opaque(int p_x, int p_y) const { int x = p_x * aw / size.x; int y = p_y * ah / size.y; - x = CLAMP(x, 0, aw); - y = CLAMP(y, 0, ah); + x = CLAMP(x, 0, aw - 1); + y = CLAMP(y, 0, ah - 1); return alpha_cache->get_bit(x, y); } diff --git a/scene/theme/default_theme.cpp b/scene/theme/default_theme.cpp index f9b21faaa81..cb7c95e3857 100644 --- a/scene/theme/default_theme.cpp +++ b/scene/theme/default_theme.cpp @@ -38,16 +38,12 @@ #include "scene/resources/image_texture.h" #include "scene/resources/style_box_flat.h" #include "scene/resources/style_box_line.h" +#include "scene/resources/svg_texture.h" #include "scene/resources/theme.h" #include "scene/scene_string_names.h" #include "scene/theme/theme_db.h" #include "servers/text_server.h" -#include "modules/modules_enabled.gen.h" // For svg. -#ifdef MODULE_SVG_ENABLED -#include "modules/svg/image_loader_svg.h" -#endif - static const int default_font_size = 16; static float scale = 1.0; @@ -80,26 +76,8 @@ static Ref sb_expand(Ref p_sbox, float p_left, float } // See also `editor_generate_icon()` in `editor/themes/editor_icons.cpp`. -static Ref generate_icon(int p_index) { - Ref img = memnew(Image); - -#ifdef MODULE_SVG_ENABLED - // Upsample icon generation only if the scale isn't an integer multiplier. - // Generating upsampled icons is slower, and the benefit is hardly visible - // with integer scales. - const bool upsample = !Math::is_equal_approx(Math::round(scale), scale); - - Error err = ImageLoaderSVG::create_image_from_string(img, default_theme_icons_sources[p_index], scale, upsample, HashMap()); - ERR_FAIL_COND_V_MSG(err != OK, Ref(), "Failed generating icon, unsupported or invalid SVG data in default theme."); - - img->fix_alpha_edges(); -#else - // If the SVG module is disabled, we can't really display the UI well, but at least we won't crash. - // 16 pixels is used as it's the most common base size for Godot icons. - img = Image::create_empty(Math::round(16 * scale), Math::round(16 * scale), false, Image::FORMAT_RGBA8); -#endif - - return ImageTexture::create_from_image(img); +static Ref generate_icon(int p_index) { + return SVGTexture::create_from_string(default_theme_icons_sources[p_index], scale); } static Ref make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {