Fix auto size rendering of SVG images in Markdown (#36663)
Release Notes: - Fixed auto size rendering of SVG images in Markdown. ## Before <img width="836" height="844" alt="image" src="https://github.com/user-attachments/assets/0782e17e-620f-4c29-a5bc-a2ffe877d220" /> <img width="691" height="678" alt="image" src="https://github.com/user-attachments/assets/dbe2dd5f-fd5b-48f9-bd09-0ee35e116aec" /> ## After <img width="873" height="1015" alt="image" src="https://github.com/user-attachments/assets/59cbb69f-6a81-43cb-989f-3bcea873d81e" /> <img width="647" height="598" alt="image" src="https://github.com/user-attachments/assets/11b67d8e-2b6c-4245-ad13-d4616fdabf22" /> For GPUI example ``` cargo run -p gpui --example image ``` <img width="1212" height="740" alt="SCR-20250821-ojoy" src="https://github.com/user-attachments/assets/62bb2847-c533-4c4d-b5f7-c9764796262a" />
This commit is contained in:
@@ -75,64 +75,70 @@ impl Render for ImageShowcase {
|
||||
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> 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()),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<Pixels> {
|
||||
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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user