From d0c5b3f2d9e20dcf67279824d837b7305930f954 Mon Sep 17 00:00:00 2001 From: Eddy Otsutsuki <23711001+hypernova7@users.noreply.github.com> Date: Tue, 6 Aug 2024 15:18:38 -0600 Subject: [PATCH] Improve svg handler with fill attribute Move svg_to_pixbuf functionality inside image widget block Preserve the aspect ratio if one of least image-width/image-height is defined Don't set default size --- crates/eww/src/widgets/widget_definitions.rs | 80 +++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/crates/eww/src/widgets/widget_definitions.rs b/crates/eww/src/widgets/widget_definitions.rs index aeb04a93..df24a745 100644 --- a/crates/eww/src/widgets/widget_definitions.rs +++ b/crates/eww/src/widgets/widget_definitions.rs @@ -527,38 +527,6 @@ fn parse_icon_size(o: &str) -> Result { } } -fn svg_to_pixbuf( - path: std::path::PathBuf, - image_width: i32, - image_height: i32, - fill: &str, -) -> Result> { - let svg_data: String = std::fs::read_to_string(path)?; - - // The fastest way to add/change fill color - let svg_data = if svg_data.contains("fill=") { - let reg = regex::Regex::new(r#"fill="[^"]*""#)?; - reg.replace(&svg_data, &format!("fill=\"{}\"", fill)) - } else { - let reg = regex::Regex::new(r" 0 || h > 0 => pixbuf_svg.set_size(w, h), - // Add default size to prevent widget overflowing, if image is too big - _ => pixbuf_svg.set_size(24, 24), - }; - - let svg_buf: Vec = svg_data.as_bytes().to_vec(); - pixbuf_svg.write(&svg_buf)?; - pixbuf_svg.close()?; - - Ok(pixbuf_svg.pixbuf()) -} - const WIDGET_NAME_IMAGE: &str = "image"; /// @widget image /// @desc A widget displaying an image @@ -568,17 +536,55 @@ fn build_gtk_image(bargs: &mut BuilderArgs) -> Result { // @prop path - path to the image file // @prop image-width - width of the image // @prop image-height - height of the image - prop(path: as_string, image_width: as_i32 = -1, image_height: as_i32 = -1, fill: as_string = "currentColor") { - if fill != "currentColor" && !path.ends_with(".svg") { + prop(path: as_string, image_width: as_i32 = -1, image_height: as_i32 = -1, fill: as_string = "") { + if !path.ends_with(".svg") && !fill.is_empty() { log::warn!("The fill attribute is only for SVG images"); } if path.ends_with(".gif") { let pixbuf_animation = gtk::gdk_pixbuf::PixbufAnimation::from_file(std::path::PathBuf::from(path))?; gtk_widget.set_from_animation(&pixbuf_animation); - } else if path.ends_with(".svg") { - let pixbuf_svg = svg_to_pixbuf(std::path::PathBuf::from(path), image_width, image_width, &fill)?; - gtk_widget.set_from_pixbuf(pixbuf_svg.as_ref()); + } else if path.ends_with(".svg") && !fill.is_empty() { + let svg_data = std::fs::read_to_string(std::path::PathBuf::from(path.clone()))?; + + // The fastest way to add/change fill color + let svg_data = if svg_data.contains("fill=") { + let reg = regex::Regex::new(r#"fill="[^"]*""#)?; + reg.replace(&svg_data, &format!("fill=\"{}\"", fill)) + } else { + let reg = regex::Regex::new(r"= 0 => pixbuf_svg.set_size(w, (aspect_ratio_h * w as f64) as i32), + // If only define the image-height attribute, then preserve the aspect ratio for the svg width + (_, h) if h >= 0 => pixbuf_svg.set_size((aspect_ratio_w * h as f64) as i32, h), + // If both attributes image-width and image-height are difined, then use it + (w, h) if w >= 0 && h >= 0 => pixbuf_svg.set_size(w, h), + _ => {} + }; + }); + pixbuf_svg.write(svg_data.as_bytes())?; + pixbuf_svg.close()?; + + gtk_widget.set_from_pixbuf(pixbuf_svg.pixbuf().as_ref()); } else { let pixbuf = gtk::gdk_pixbuf::Pixbuf::from_file_at_size(std::path::PathBuf::from(path), image_width, image_height)?; gtk_widget.set_from_pixbuf(Some(&pixbuf));