Browse Source

optimized color conversion for svg generation

toger5 8 years ago
parent
commit
ee5dc05a09
3 changed files with 56 additions and 38 deletions
  1. 16 9
      editor/editor_themes.cpp
  2. 32 25
      modules/svg/image_loader_svg.cpp
  3. 8 4
      modules/svg/image_loader_svg.h

+ 16 - 9
editor/editor_themes.cpp

@@ -86,7 +86,7 @@ static Ref<StyleBoxFlat> change_border_color(Ref<StyleBoxFlat> p_style, Color p_
 	return style;
 	return style;
 }
 }
 
 
-Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true, Dictionary *p_colors = NULL, float p_scale = EDSCALE, bool force_filter = false) {
+Ref<ImageTexture> editor_generate_icon(int p_index, bool convert_color, float p_scale = EDSCALE, bool force_filter = false) {
 
 
 	Ref<ImageTexture> icon = memnew(ImageTexture);
 	Ref<ImageTexture> icon = memnew(ImageTexture);
 	Ref<Image> img = memnew(Image);
 	Ref<Image> img = memnew(Image);
@@ -94,7 +94,7 @@ Ref<ImageTexture> editor_generate_icon(int p_index, bool dark_theme = true, Dict
 	// dumb gizmo check
 	// dumb gizmo check
 	bool is_gizmo = String(editor_icons_names[p_index]).begins_with("Gizmo");
 	bool is_gizmo = String(editor_icons_names[p_index]).begins_with("Gizmo");
 
 
-	ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, true, dark_theme ? NULL : p_colors);
+	ImageLoaderSVG::create_image_from_string(img, editor_icons_sources[p_index], p_scale, true, convert_color);
 
 
 	if ((p_scale - (float)((int)p_scale)) > 0.0 || is_gizmo || force_filter)
 	if ((p_scale - (float)((int)p_scale)) > 0.0 || is_gizmo || force_filter)
 		icon->create_from_image(img); // in this case filter really helps
 		icon->create_from_image(img); // in this case filter really helps
@@ -160,34 +160,41 @@ void editor_register_and_generate_icons(Ref<Theme> p_theme, bool dark_theme = tr
 
 
 	clock_t begin_time = clock();
 	clock_t begin_time = clock();
 
 
+	ImageLoaderSVG::set_convert_colors(dark_theme ? NULL : &dark_icon_color_dictionary);
+
+	// generate icons
 	if (!only_thumbs)
 	if (!only_thumbs)
 		for (int i = 0; i < editor_icons_count; i++) {
 		for (int i = 0; i < editor_icons_count; i++) {
 			List<String>::Element *is_exception = exceptions.find(editor_icons_names[i]);
 			List<String>::Element *is_exception = exceptions.find(editor_icons_names[i]);
-			if (is_exception) {
-				exceptions.erase(is_exception);
-			}
-			Ref<ImageTexture> icon = editor_generate_icon(i, dark_theme, is_exception ? NULL : &dark_icon_color_dictionary);
+			if (is_exception) exceptions.erase(is_exception);
+			Ref<ImageTexture> icon = editor_generate_icon(i, !dark_theme && !is_exception);
 			p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
 			p_theme->set_icon(editor_icons_names[i], "EditorIcons", icon);
 		}
 		}
 
 
-	bool force_filter = !(p_thumb_size == 64 && p_thumb_size == 32); // we dont need filter with original resolution
 	// generate thumb files with the given thumb size
 	// generate thumb files with the given thumb size
+	bool force_filter = !(p_thumb_size == 64 && p_thumb_size == 32); // we dont need filter with original resolution
 	if (p_thumb_size >= 64) {
 	if (p_thumb_size >= 64) {
 		float scale = (float)p_thumb_size / 64.0 * EDSCALE;
 		float scale = (float)p_thumb_size / 64.0 * EDSCALE;
 		for (int i = 0; i < editor_bg_thumbs_count; i++) {
 		for (int i = 0; i < editor_bg_thumbs_count; i++) {
 			int index = editor_bg_thumbs_indices[i];
 			int index = editor_bg_thumbs_indices[i];
-			Ref<ImageTexture> icon = editor_generate_icon(index, dark_theme, &dark_icon_color_dictionary, scale, force_filter);
+			List<String>::Element *is_exception = exceptions.find(editor_icons_names[index]);
+			if (is_exception) exceptions.erase(is_exception);
+			Ref<ImageTexture> icon = editor_generate_icon(index, !dark_theme && !is_exception, scale, force_filter);
 			p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
 			p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
 		}
 		}
 	} else {
 	} else {
 		float scale = (float)p_thumb_size / 32.0 * EDSCALE;
 		float scale = (float)p_thumb_size / 32.0 * EDSCALE;
 		for (int i = 0; i < editor_md_thumbs_count; i++) {
 		for (int i = 0; i < editor_md_thumbs_count; i++) {
 			int index = editor_md_thumbs_indices[i];
 			int index = editor_md_thumbs_indices[i];
-			Ref<ImageTexture> icon = editor_generate_icon(index, dark_theme, &dark_icon_color_dictionary, scale, force_filter);
+			List<String>::Element *is_exception = exceptions.find(editor_icons_names[index]);
+			if (is_exception) exceptions.erase(is_exception);
+			Ref<ImageTexture> icon = editor_generate_icon(index, !dark_theme && !is_exception, scale, force_filter);
 			p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
 			p_theme->set_icon(editor_icons_names[index], "EditorIcons", icon);
 		}
 		}
 	}
 	}
 
 
+	ImageLoaderSVG::set_convert_colors(NULL);
+
 	clock_t end_time = clock();
 	clock_t end_time = clock();
 
 
 	double time_d = (double)(end_time - begin_time) / CLOCKS_PER_SEC;
 	double time_d = (double)(end_time - begin_time) / CLOCKS_PER_SEC;

+ 32 - 25
modules/svg/image_loader_svg.cpp

@@ -63,33 +63,39 @@ inline void change_nsvg_paint_color(NSVGpaint *p_paint, const uint32_t p_old, co
 		}
 		}
 	}
 	}
 }
 }
-void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image, const Dictionary p_colors) {
-	List<uint32_t> replace_colors_i;
-	List<uint32_t> new_colors_i;
-	List<Color> replace_colors;
-	List<Color> new_colors;
-
-	for (int i = 0; i < p_colors.keys().size(); i++) {
-		Variant r_c = p_colors.keys()[i];
-		Variant n_c = p_colors[p_colors.keys()[i]];
-		if (r_c.get_type() == Variant::COLOR && n_c.get_type() == Variant::COLOR) {
-			Color replace_color = r_c;
-			Color new_color = n_c;
-			replace_colors_i.push_back(replace_color.to_abgr32());
-			new_colors_i.push_back(new_color.to_abgr32());
-		}
-	}
+
+void ImageLoaderSVG::_convert_colors(NSVGimage *p_svg_image) {
 
 
 	for (NSVGshape *shape = p_svg_image->shapes; shape != NULL; shape = shape->next) {
 	for (NSVGshape *shape = p_svg_image->shapes; shape != NULL; shape = shape->next) {
 
 
-		for (int i = 0; i < replace_colors_i.size(); i++) {
-			change_nsvg_paint_color(&(shape->stroke), replace_colors_i[i], new_colors_i[i]);
-			change_nsvg_paint_color(&(shape->fill), replace_colors_i[i], new_colors_i[i]);
+		for (int i = 0; i < replace_colors.old_colors.size(); i++) {
+			change_nsvg_paint_color(&(shape->stroke), replace_colors.old_colors[i], replace_colors.new_colors[i]);
+			change_nsvg_paint_color(&(shape->fill), replace_colors.old_colors[i], replace_colors.new_colors[i]);
+		}
+	}
+}
+
+void ImageLoaderSVG::set_convert_colors(Dictionary *p_replace_color) {
+
+	if (p_replace_color) {
+		Dictionary replace_color = *p_replace_color;
+		for (int i = 0; i < replace_color.keys().size(); i++) {
+			Variant o_c = replace_color.keys()[i];
+			Variant n_c = replace_color[replace_color.keys()[i]];
+			if (o_c.get_type() == Variant::COLOR && n_c.get_type() == Variant::COLOR) {
+				Color old_color = o_c;
+				Color new_color = n_c;
+				replace_colors.old_colors.push_back(old_color.to_abgr32());
+				replace_colors.new_colors.push_back(new_color.to_abgr32());
+			}
 		}
 		}
+	} else {
+		replace_colors.old_colors.clear();
+		replace_colors.new_colors.clear();
 	}
 	}
 }
 }
 
 
-Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, const Dictionary *p_replace_colors) {
+Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors) {
 	NSVGimage *svg_image;
 	NSVGimage *svg_image;
 	PoolVector<uint8_t>::Read src_r = p_data->read();
 	PoolVector<uint8_t>::Read src_r = p_data->read();
 	svg_image = nsvgParse((char *)src_r.ptr(), "px", 96);
 	svg_image = nsvgParse((char *)src_r.ptr(), "px", 96);
@@ -97,10 +103,9 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
 		ERR_PRINT("SVG Corrupted");
 		ERR_PRINT("SVG Corrupted");
 		return ERR_FILE_CORRUPT;
 		return ERR_FILE_CORRUPT;
 	}
 	}
+	if (convert_colors)
+		_convert_colors(svg_image);
 
 
-	if (p_replace_colors != NULL) {
-		_convert_colors(svg_image, *p_replace_colors);
-	}
 	float upscale = upsample ? 2.0 : 1.0;
 	float upscale = upsample ? 2.0 : 1.0;
 
 
 	int w = (int)(svg_image->width * p_scale * upscale);
 	int w = (int)(svg_image->width * p_scale * upscale);
@@ -123,7 +128,7 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t
 	return OK;
 	return OK;
 }
 }
 
 
-Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *svg_str, float p_scale, bool upsample, const Dictionary *p_replace_colors) {
+Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *svg_str, float p_scale, bool upsample, bool convert_colors) {
 
 
 	size_t str_len = strlen(svg_str);
 	size_t str_len = strlen(svg_str);
 	PoolVector<uint8_t> src_data;
 	PoolVector<uint8_t> src_data;
@@ -131,7 +136,7 @@ Error ImageLoaderSVG::create_image_from_string(Ref<Image> p_image, const char *s
 	PoolVector<uint8_t>::Write src_w = src_data.write();
 	PoolVector<uint8_t>::Write src_w = src_data.write();
 	memcpy(src_w.ptr(), svg_str, str_len + 1);
 	memcpy(src_w.ptr(), svg_str, str_len + 1);
 
 
-	return _create_image(p_image, &src_data, p_scale, upsample, p_replace_colors);
+	return _create_image(p_image, &src_data, p_scale, upsample, convert_colors);
 }
 }
 
 
 Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
 Error ImageLoaderSVG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale) {
@@ -154,3 +159,5 @@ void ImageLoaderSVG::get_recognized_extensions(List<String> *p_extensions) const
 
 
 ImageLoaderSVG::ImageLoaderSVG() {
 ImageLoaderSVG::ImageLoaderSVG() {
 }
 }
+
+ImageLoaderSVG::ReplaceColors ImageLoaderSVG::replace_colors;

+ 8 - 4
modules/svg/image_loader_svg.h

@@ -52,13 +52,17 @@ public:
 };
 };
 
 
 class ImageLoaderSVG : public ImageFormatLoader {
 class ImageLoaderSVG : public ImageFormatLoader {
-
+	static struct ReplaceColors {
+		List<uint32_t> old_colors;
+		List<uint32_t> new_colors;
+	} replace_colors;
 	static SVGRasterizer rasterizer;
 	static SVGRasterizer rasterizer;
-	static void _convert_colors(NSVGimage *p_svg_imge, const Dictionary p_colors);
-	static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, const Dictionary *p_replace_color = NULL);
+	static void _convert_colors(NSVGimage *p_svg_imge);
+	static Error _create_image(Ref<Image> p_image, const PoolVector<uint8_t> *p_data, float p_scale, bool upsample, bool convert_colors = false);
 
 
 public:
 public:
-	static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, const Dictionary *p_replace_color = NULL);
+	static void set_convert_colors(Dictionary *p_replace_color = NULL);
+	static Error create_image_from_string(Ref<Image> p_image, const char *p_svg_str, float p_scale, bool upsample, bool convert_colors = false);
 
 
 	virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
 	virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear, float p_scale);
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;
 	virtual void get_recognized_extensions(List<String> *p_extensions) const;