diff --git a/crates/gpui/examples/image/image.rs b/crates/gpui/examples/image/image.rs index bd1708e8c4..34a510f76d 100644 --- a/crates/gpui/examples/image/image.rs +++ b/crates/gpui/examples/image/image.rs @@ -75,64 +75,70 @@ impl Render for ImageShowcase { fn render(&mut self, _window: &mut Window, _cx: &mut Context) -> impl IntoElement { div() .id("main") + .bg(gpui::white()) .overflow_y_scroll() .p_5() .size_full() - .flex() - .flex_col() - .justify_center() - .items_center() - .gap_8() - .bg(rgb(0xffffff)) - .child( - div() - .flex() - .flex_row() - .justify_center() - .items_center() - .gap_8() - .child(ImageContainer::new( - "Image loaded from a local file", - self.local_resource.clone(), - )) - .child(ImageContainer::new( - "Image loaded from a remote resource", - self.remote_resource.clone(), - )) - .child(ImageContainer::new( - "Image loaded from an asset", - self.asset_resource.clone(), - )), - ) - .child( - div() - .flex() - .flex_row() - .gap_8() - .child( - div() - .flex_col() - .child("Auto Width") - .child(img("https://picsum.photos/800/400").h(px(180.))), - ) - .child( - div() - .flex_col() - .child("Auto Height") - .child(img("https://picsum.photos/800/400").w(px(180.))), - ), - ) .child( div() .flex() .flex_col() .justify_center() .items_center() - .w_full() - .border_1() - .border_color(rgb(0xC0C0C0)) - .child("image with max width 100%") - .child(img("https://picsum.photos/800/400").max_w_full()), + .gap_8() + .child(img( + "https://github.com/zed-industries/zed/actions/workflows/ci.yml/badge.svg", + )) + .child( + div() + .flex() + .flex_row() + .justify_center() + .items_center() + .gap_8() + .child(ImageContainer::new( + "Image loaded from a local file", + self.local_resource.clone(), + )) + .child(ImageContainer::new( + "Image loaded from a remote resource", + self.remote_resource.clone(), + )) + .child(ImageContainer::new( + "Image loaded from an asset", + self.asset_resource.clone(), + )), + ) + .child( + div() + .flex() + .flex_row() + .gap_8() + .child( + div() + .flex_col() + .child("Auto Width") + .child(img("https://picsum.photos/800/400").h(px(180.))), + ) + .child( + div() + .flex_col() + .child("Auto Height") + .child(img("https://picsum.photos/800/400").w(px(180.))), + ), + ) + .child( + div() + .flex() + .flex_col() + .justify_center() + .items_center() + .w_full() + .border_1() + .border_color(rgb(0xC0C0C0)) + .child("image with max width 100%") + .child(img("https://picsum.photos/800/400").max_w_full()), + ), ) } } diff --git a/crates/gpui/src/assets.rs b/crates/gpui/src/assets.rs index 70a07c11e9..8930b58f8d 100644 --- a/crates/gpui/src/assets.rs +++ b/crates/gpui/src/assets.rs @@ -1,4 +1,4 @@ -use crate::{DevicePixels, Result, SharedString, Size, size}; +use crate::{DevicePixels, Pixels, Result, SharedString, Size, size}; use smallvec::SmallVec; use image::{Delay, Frame}; @@ -42,6 +42,8 @@ pub(crate) struct RenderImageParams { pub struct RenderImage { /// The ID associated with this image pub id: ImageId, + /// The scale factor of this image on render. + pub(crate) scale_factor: f32, data: SmallVec<[Frame; 1]>, } @@ -60,6 +62,7 @@ impl RenderImage { Self { id: ImageId(NEXT_ID.fetch_add(1, SeqCst)), + scale_factor: 1.0, data: data.into(), } } @@ -77,6 +80,12 @@ impl RenderImage { size(width.into(), height.into()) } + /// Get the size of this image, in pixels for display, adjusted for the scale factor. + pub(crate) fn render_size(&self, frame_index: usize) -> Size { + self.size(frame_index) + .map(|v| (v.0 as f32 / self.scale_factor).into()) + } + /// Get the delay of this frame from the previous pub fn delay(&self, frame_index: usize) -> Delay { self.data[frame_index].delay() diff --git a/crates/gpui/src/elements/img.rs b/crates/gpui/src/elements/img.rs index 893860d7e1..40d1b5e449 100644 --- a/crates/gpui/src/elements/img.rs +++ b/crates/gpui/src/elements/img.rs @@ -332,20 +332,18 @@ impl Element for Img { state.started_loading = None; } - let image_size = data.size(frame_index); - style.aspect_ratio = - Some(image_size.width.0 as f32 / image_size.height.0 as f32); + let image_size = data.render_size(frame_index); + style.aspect_ratio = Some(image_size.width / image_size.height); if let Length::Auto = style.size.width { style.size.width = match style.size.height { Length::Definite(DefiniteLength::Absolute( AbsoluteLength::Pixels(height), )) => Length::Definite( - px(image_size.width.0 as f32 * height.0 - / image_size.height.0 as f32) - .into(), + px(image_size.width.0 * height.0 / image_size.height.0) + .into(), ), - _ => Length::Definite(px(image_size.width.0 as f32).into()), + _ => Length::Definite(image_size.width.into()), }; } @@ -354,11 +352,10 @@ impl Element for Img { Length::Definite(DefiniteLength::Absolute( AbsoluteLength::Pixels(width), )) => Length::Definite( - px(image_size.height.0 as f32 * width.0 - / image_size.width.0 as f32) - .into(), + px(image_size.height.0 * width.0 / image_size.width.0) + .into(), ), - _ => Length::Definite(px(image_size.height.0 as f32).into()), + _ => Length::Definite(image_size.height.into()), }; } @@ -701,7 +698,9 @@ impl Asset for ImageAssetLoader { swap_rgba_pa_to_bgra(pixel); } - RenderImage::new(SmallVec::from_elem(Frame::new(buffer), 1)) + let mut image = RenderImage::new(SmallVec::from_elem(Frame::new(buffer), 1)); + image.scale_factor = SMOOTH_SVG_SCALE_FACTOR; + image }; Ok(Arc::new(data))