summaryrefslogtreecommitdiff
path: root/modules/svg/image_loader_svg.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/svg/image_loader_svg.cpp')
-rw-r--r--modules/svg/image_loader_svg.cpp40
1 files changed, 26 insertions, 14 deletions
diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp
index 87e2fae2d0..b8c412a201 100644
--- a/modules/svg/image_loader_svg.cpp
+++ b/modules/svg/image_loader_svg.cpp
@@ -35,13 +35,19 @@
#include <thorvg.h>
-void ImageLoaderSVG::_replace_color_property(const String &p_prefix, String &r_string) {
- // Replace colors in the SVG based on what is configured in `replace_colors`.
+HashMap<Color, Color> ImageLoaderSVG::forced_color_map = HashMap<Color, Color>();
+
+void ImageLoaderSVG::set_forced_color_map(const HashMap<Color, Color> &p_color_map) {
+ forced_color_map = p_color_map;
+}
+
+void ImageLoaderSVG::_replace_color_property(const HashMap<Color, Color> &p_color_map, const String &p_prefix, String &r_string) {
+ // Replace colors in the SVG based on what is passed in `p_color_map`.
// Used to change the colors of editor icons based on the used theme.
// The strings being replaced are typically of the form:
// fill="#5abbef"
// But can also be 3-letter codes, include alpha, be "none" or a named color
- // string ("blue"). So we convert to Godot Color to compare with `replace_colors`.
+ // string ("blue"). So we convert to Godot Color to compare with `p_color_map`.
const int prefix_len = p_prefix.length();
int pos = r_string.find(p_prefix);
@@ -52,8 +58,8 @@ void ImageLoaderSVG::_replace_color_property(const String &p_prefix, String &r_s
const String color_code = r_string.substr(pos, end_pos - pos);
if (color_code != "none" && !color_code.begins_with("url(")) {
const Color color = Color(color_code); // Handles both HTML codes and named colors.
- if (replace_colors.has(color)) {
- r_string = r_string.left(pos) + "#" + replace_colors[color].operator Color().to_html(false) + r_string.substr(end_pos);
+ if (p_color_map.has(color)) {
+ r_string = r_string.left(pos) + "#" + p_color_map[color].to_html(false) + r_string.substr(end_pos);
}
}
// Search for other occurrences.
@@ -61,13 +67,13 @@ void ImageLoaderSVG::_replace_color_property(const String &p_prefix, String &r_s
}
}
-void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_string, float p_scale, bool p_upsample, bool p_convert_color) {
+void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_string, float p_scale, bool p_upsample, const HashMap<Color, Color> &p_color_map) {
ERR_FAIL_COND(Math::is_zero_approx(p_scale));
- if (p_convert_color) {
- _replace_color_property("stop-color=\"", p_string);
- _replace_color_property("fill=\"", p_string);
- _replace_color_property("stroke=\"", p_string);
+ if (p_color_map.size()) {
+ _replace_color_property(p_color_map, "stop-color=\"", p_string);
+ _replace_color_property(p_color_map, "fill=\"", p_string);
+ _replace_color_property(p_color_map, "stroke=\"", p_string);
}
std::unique_ptr<tvg::Picture> picture = tvg::Picture::gen();
@@ -129,18 +135,24 @@ void ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, String p_strin
res = sw_canvas->clear(true);
memfree(buffer);
- p_image->create(width, height, false, Image::FORMAT_RGBA8, image);
+ p_image->set_data(width, height, false, Image::FORMAT_RGBA8, image);
}
void ImageLoaderSVG::get_recognized_extensions(List<String> *p_extensions) const {
p_extensions->push_back("svg");
}
-Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, bool p_force_linear, float p_scale) {
+Error ImageLoaderSVG::load_image(Ref<Image> p_image, Ref<FileAccess> p_fileaccess, BitField<ImageFormatLoader::LoaderFlags> p_flags, float p_scale) {
String svg = p_fileaccess->get_as_utf8_string();
- create_image_from_string(p_image, svg, p_scale, false, false);
+
+ if (p_flags & FLAG_CONVERT_COLORS) {
+ create_image_from_string(p_image, svg, p_scale, false, forced_color_map);
+ } else {
+ create_image_from_string(p_image, svg, p_scale, false, HashMap<Color, Color>());
+ }
+
ERR_FAIL_COND_V(p_image->is_empty(), FAILED);
- if (p_force_linear) {
+ if (p_flags & FLAG_FORCE_LINEAR) {
p_image->srgb_to_linear();
}
return OK;