Implement rendering of images with data urls in markdown (#30322)

Fixes #28266

![Screenshot 2025-05-08 at 5 08
21 PM](https://github.com/user-attachments/assets/774d2dde-3f2d-466c-8eb1-c67badbd89e4)

Release Notes:

- Added support for rendering images with data URLs in markdown. This
can show up in hover documentation provided by language servers.

Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
This commit is contained in:
Max Brunsfeld
2025-05-08 18:26:24 -07:00
committed by GitHub
co-authored by Mikayla Maki
parent c512d43e8c
commit 29c31f020e
9 changed files with 131 additions and 42 deletions
+24 -5
View File
@@ -36,7 +36,7 @@ use crate::{
ForegroundExecutor, GlyphId, GpuSpecs, ImageSource, Keymap, LineLayout, Pixels, PlatformInput,
Point, RenderGlyphParams, RenderImage, RenderImageParams, RenderSvgParams, ScaledPixels, Scene,
ShapedGlyph, ShapedRun, SharedString, Size, SvgRenderer, SvgSize, Task, TaskLabel, Window,
point, px, size,
hash, point, px, size,
};
use anyhow::Result;
use async_task::Runnable;
@@ -1499,6 +1499,20 @@ impl ImageFormat {
ImageFormat::Tiff => "image/tiff",
}
}
/// Returns the ImageFormat for the given mime type
pub fn from_mime_type(mime_type: &str) -> Option<Self> {
match mime_type {
"image/png" => Some(Self::Png),
"image/jpeg" | "image/jpg" => Some(Self::Jpeg),
"image/webp" => Some(Self::Webp),
"image/gif" => Some(Self::Gif),
"image/svg+xml" => Some(Self::Svg),
"image/bmp" => Some(Self::Bmp),
"image/tiff" | "image/tif" => Some(Self::Tiff),
_ => None,
}
}
}
/// An image, with a format and certain bytes
@@ -1509,7 +1523,7 @@ pub struct Image {
/// The raw image bytes
pub bytes: Vec<u8>,
/// The unique ID for the image
pub id: u64,
id: u64,
}
impl Hash for Image {
@@ -1521,10 +1535,15 @@ impl Hash for Image {
impl Image {
/// An empty image containing no data
pub fn empty() -> Self {
Self::from_bytes(ImageFormat::Png, Vec::new())
}
/// Create an image from a format and bytes
pub fn from_bytes(format: ImageFormat, bytes: Vec<u8>) -> Self {
Self {
format: ImageFormat::Png,
bytes: Vec::new(),
id: 0,
id: hash(&bytes),
format,
bytes,
}
}
+2 -2
View File
@@ -2100,14 +2100,14 @@ impl Window {
let (task, is_first) = cx.fetch_asset::<A>(source);
task.clone().now_or_never().or_else(|| {
if is_first {
let entity = self.current_view();
let entity_id = self.current_view();
self.spawn(cx, {
let task = task.clone();
async move |cx| {
task.await;
cx.on_next_frame(move |_, cx| {
cx.notify(entity);
cx.notify(entity_id);
});
}
})