Handle more already supported image formats across the codebase (#54326)
This commit is contained in:
1 parent
7fd07dda55
commit
c92833611e
3 files changed
+40
-50
No files matched your search
@@ -839,7 +839,11 @@ fn image_format_from_external_content(format: image::ImageFormat) -> Option<Imag
|
||||
image::ImageFormat::Bmp => Some(ImageFormat::Bmp),
|
||||
image::ImageFormat::Tiff => Some(ImageFormat::Tiff),
|
||||
image::ImageFormat::Ico => Some(ImageFormat::Ico),
|
||||
_ => None,
|
||||
image::ImageFormat::Pnm => Some(ImageFormat::Pnm),
|
||||
_ => {
|
||||
debug_panic!("An unhandled image format: {format:?}");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2001,17 +2001,21 @@ impl ImageFormat {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the ImageFormat for the given mime type
|
||||
/// Returns the ImageFormat for the given mime type, including known aliases.
|
||||
pub fn from_mime_type(mime_type: &str) -> Option<Self> {
|
||||
use strum::IntoEnumIterator;
|
||||
Self::iter()
|
||||
.find(|format| format.mime_type() == mime_type)
|
||||
.or_else(|| Self::from_mime_type_alias(mime_type))
|
||||
}
|
||||
|
||||
/// Non-canonical mime types that some producers use in the wild.
|
||||
/// Unlike `mime_type()` which returns the single canonical form,
|
||||
/// these are legacy or shortened variants we still need to recognize.
|
||||
fn from_mime_type_alias(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),
|
||||
"image/ico" => Some(Self::Ico),
|
||||
"image/jpg" => Some(Self::Jpeg),
|
||||
"image/tif" => Some(Self::Tiff),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ use x11rb::{
|
||||
};
|
||||
|
||||
use gpui::{ClipboardItem, Image, ImageFormat, hash};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
type Result<T, E = Error> = std::result::Result<T, E>;
|
||||
|
||||
@@ -989,14 +990,8 @@ impl Clipboard {
|
||||
self.inner.write(data, selection, wait)
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) fn set_image(
|
||||
&self,
|
||||
image: Image,
|
||||
selection: ClipboardKind,
|
||||
wait: WaitConfig,
|
||||
) -> Result<()> {
|
||||
let format = match image.format {
|
||||
fn image_format_atom(&self, format: ImageFormat) -> Atom {
|
||||
match format {
|
||||
ImageFormat::Png => self.inner.atoms.PNG__MIME,
|
||||
ImageFormat::Jpeg => self.inner.atoms.JPEG_MIME,
|
||||
ImageFormat::Webp => self.inner.atoms.WEBP_MIME,
|
||||
@@ -1006,7 +1001,17 @@ impl Clipboard {
|
||||
ImageFormat::Tiff => self.inner.atoms.TIFF_MIME,
|
||||
ImageFormat::Ico => self.inner.atoms.ICO__MIME,
|
||||
ImageFormat::Pnm => self.inner.atoms.PNM__MIME,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub(crate) fn set_image(
|
||||
&self,
|
||||
image: Image,
|
||||
selection: ClipboardKind,
|
||||
wait: WaitConfig,
|
||||
) -> Result<()> {
|
||||
let format = self.image_format_atom(image.format);
|
||||
let data = vec![ClipboardData {
|
||||
bytes: image.bytes,
|
||||
format: self.inner.atoms.PNG__MIME,
|
||||
@@ -1015,28 +1020,11 @@ impl Clipboard {
|
||||
}
|
||||
|
||||
pub(crate) fn get_any(&self, selection: ClipboardKind) -> Result<ClipboardItem> {
|
||||
const IMAGE_FORMAT_COUNT: usize = 7;
|
||||
let image_format_atoms: [Atom; IMAGE_FORMAT_COUNT] = [
|
||||
self.inner.atoms.PNG__MIME,
|
||||
self.inner.atoms.JPEG_MIME,
|
||||
self.inner.atoms.WEBP_MIME,
|
||||
self.inner.atoms.GIF__MIME,
|
||||
self.inner.atoms.SVG__MIME,
|
||||
self.inner.atoms.BMP__MIME,
|
||||
self.inner.atoms.TIFF_MIME,
|
||||
];
|
||||
let image_formats: [ImageFormat; IMAGE_FORMAT_COUNT] = [
|
||||
ImageFormat::Png,
|
||||
ImageFormat::Jpeg,
|
||||
ImageFormat::Webp,
|
||||
ImageFormat::Gif,
|
||||
ImageFormat::Svg,
|
||||
ImageFormat::Bmp,
|
||||
ImageFormat::Tiff,
|
||||
];
|
||||
let image_entries = ImageFormat::iter()
|
||||
.map(|format| (self.image_format_atom(format), format))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
const TEXT_FORMAT_COUNT: usize = 6;
|
||||
let text_format_atoms: [Atom; TEXT_FORMAT_COUNT] = [
|
||||
let text_format_atoms: &[Atom] = &[
|
||||
self.inner.atoms.UTF8_STRING,
|
||||
self.inner.atoms.UTF8_MIME_0,
|
||||
self.inner.atoms.UTF8_MIME_1,
|
||||
@@ -1045,17 +1033,11 @@ impl Clipboard {
|
||||
self.inner.atoms.TEXT_MIME_UNKNOWN,
|
||||
];
|
||||
|
||||
let atom_none: Atom = AtomEnum::NONE.into();
|
||||
|
||||
const FORMAT_ATOM_COUNT: usize = TEXT_FORMAT_COUNT + IMAGE_FORMAT_COUNT;
|
||||
|
||||
let mut format_atoms: [Atom; FORMAT_ATOM_COUNT] = [atom_none; FORMAT_ATOM_COUNT];
|
||||
|
||||
// image formats first, as they are more specific, and read will return the first
|
||||
// format that the contents can be converted to
|
||||
format_atoms[0..IMAGE_FORMAT_COUNT].copy_from_slice(&image_format_atoms);
|
||||
format_atoms[IMAGE_FORMAT_COUNT..].copy_from_slice(&text_format_atoms);
|
||||
debug_assert!(!format_atoms.contains(&atom_none));
|
||||
let mut format_atoms = Vec::with_capacity(image_entries.len() + text_format_atoms.len());
|
||||
format_atoms.extend(image_entries.iter().map(|(atom, _)| *atom));
|
||||
format_atoms.extend_from_slice(text_format_atoms);
|
||||
|
||||
let result = self.inner.read(&format_atoms, selection)?;
|
||||
|
||||
@@ -1064,7 +1046,7 @@ impl Clipboard {
|
||||
self.inner.atom_name(result.format)
|
||||
);
|
||||
|
||||
for (format_atom, image_format) in image_format_atoms.into_iter().zip(image_formats) {
|
||||
for (format_atom, image_format) in image_entries {
|
||||
if result.format == format_atom {
|
||||
let bytes = result.bytes;
|
||||
let id = hash(&bytes);
|
||||
|
||||
Reference in new issue
Block a user