Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explain the purpose of the ImageSource::Bytes URI #3402

Merged
merged 1 commit into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions crates/egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,10 +458,10 @@ pub fn warn_if_debug_build(ui: &mut crate::Ui) {
#[macro_export]
macro_rules! include_image {
($path: literal) => {
$crate::ImageSource::Bytes(
::std::borrow::Cow::Borrowed(concat!("bytes://", $path)), // uri
$crate::load::Bytes::Static(include_bytes!($path)),
)
$crate::ImageSource::Bytes {
uri: ::std::borrow::Cow::Borrowed(concat!("bytes://", $path)),
bytes: $crate::load::Bytes::Static(include_bytes!($path)),
}
};
}

Expand Down
8 changes: 4 additions & 4 deletions crates/egui/src/load.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,15 @@ pub enum LoadError {
/// Programmer error: There are no image loaders installed.
NoImageLoaders,

/// A specific loader does not support this schema, protocol or image format.
/// A specific loader does not support this scheme, protocol or image format.
NotSupported,

/// Programmer error: Failed to find the bytes for this image because
/// there was no [`BytesLoader`] supporting the schema.
/// there was no [`BytesLoader`] supporting the scheme.
NoMatchingBytesLoader,

/// Programmer error: Failed to parse the bytes as an image because
/// there was no [`ImageLoader`] supporting the schema.
/// there was no [`ImageLoader`] supporting the scheme.
NoMatchingImageLoader,

/// Programmer error: no matching [`TextureLoader`].
Expand All @@ -111,7 +111,7 @@ impl Display for LoadError {

Self::NoMatchingTextureLoader => f.write_str("No matching TextureLoader. Did you remove the default one?"),

Self::NotSupported => f.write_str("Iagge schema or URI not supported by this loader"),
Self::NotSupported => f.write_str("Image scheme or URI not supported by this loader"),

Self::Loading(message) => f.write_str(message),
}
Expand Down
48 changes: 34 additions & 14 deletions crates/egui/src/widgets/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ impl<'a> Image<'a> {
///
/// See [`ImageSource::Bytes`].
pub fn from_bytes(uri: impl Into<Cow<'static, str>>, bytes: impl Into<Bytes>) -> Self {
Self::new(ImageSource::Bytes(uri.into(), bytes.into()))
Self::new(ImageSource::Bytes {
uri: uri.into(),
bytes: bytes.into(),
})
}

/// Texture options used when creating the texture.
Expand Down Expand Up @@ -275,7 +278,7 @@ impl<'a> Image<'a> {
pub fn size(&self) -> Option<Vec2> {
match &self.source {
ImageSource::Texture(texture) => Some(texture.size),
ImageSource::Uri(_) | ImageSource::Bytes(_, _) => None,
ImageSource::Uri(_) | ImageSource::Bytes { .. } => None,
}
}

Expand Down Expand Up @@ -478,9 +481,10 @@ impl Default for ImageSize {
/// This is used by [`Image::new`] and [`Ui::image`].
#[derive(Clone)]
pub enum ImageSource<'a> {
/// Load the image from a URI.
/// Load the image from a URI, e.g. `https://example.com/image.png`.
///
/// This could be a `file://` path, `https://` url, `bytes://` identifier, or some other scheme.
///
/// This could be a `file://` url, `http(s)?://` url, or a `bare` identifier.
/// How the URI will be turned into a texture for rendering purposes is
/// up to the registered loaders to handle.
///
Expand All @@ -495,8 +499,6 @@ pub enum ImageSource<'a> {

/// Load the image from some raw bytes.
///
/// For better error messages, use the `bytes://` prefix for the URI.
///
/// The [`Bytes`] may be:
/// - `'static`, obtained from `include_bytes!` or similar
/// - Anything that can be converted to `Arc<[u8]>`
Expand All @@ -506,13 +508,22 @@ pub enum ImageSource<'a> {
/// See also [`include_image`] for an easy way to load and display static images.
///
/// See [`crate::load`] for more information.
Bytes(Cow<'static, str>, Bytes),
Bytes {
/// The unique identifier for this image, e.g. `bytes://my_logo.png`.
///
/// You should use a proper extension (`.jpg`, `.png`, `.svg`, etc) for the image to load properly.
///
/// Use the `bytes://` scheme for the URI for better error messages.
uri: Cow<'static, str>,

bytes: Bytes,
},
}

impl<'a> std::fmt::Debug for ImageSource<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ImageSource::Bytes(uri, _) | ImageSource::Uri(uri) => uri.as_ref().fmt(f),
ImageSource::Bytes { uri, .. } | ImageSource::Uri(uri) => uri.as_ref().fmt(f),
ImageSource::Texture(st) => st.id.fmt(f),
}
}
Expand All @@ -524,7 +535,7 @@ impl<'a> ImageSource<'a> {
pub fn texture_size(&self) -> Option<Vec2> {
match self {
ImageSource::Texture(texture) => Some(texture.size),
ImageSource::Uri(_) | ImageSource::Bytes(_, _) => None,
ImageSource::Uri(_) | ImageSource::Bytes { .. } => None,
}
}

Expand All @@ -539,7 +550,7 @@ impl<'a> ImageSource<'a> {
match self {
Self::Texture(texture) => Ok(TexturePoll::Ready { texture }),
Self::Uri(uri) => ctx.try_load_texture(uri.as_ref(), texture_options, size_hint),
Self::Bytes(uri, bytes) => {
Self::Bytes { uri, bytes } => {
ctx.include_bytes(uri.clone(), bytes);
ctx.try_load_texture(uri.as_ref(), texture_options, size_hint)
}
Expand All @@ -551,7 +562,7 @@ impl<'a> ImageSource<'a> {
/// This will return `None` for [`Self::Texture`].
pub fn uri(&self) -> Option<&str> {
match self {
ImageSource::Bytes(uri, _) | ImageSource::Uri(uri) => Some(uri),
ImageSource::Bytes { uri, .. } | ImageSource::Uri(uri) => Some(uri),
ImageSource::Texture(_) => None,
}
}
Expand Down Expand Up @@ -644,21 +655,30 @@ impl<'a> From<Cow<'a, str>> for ImageSource<'a> {
impl<T: Into<Bytes>> From<(&'static str, T)> for ImageSource<'static> {
#[inline]
fn from((uri, bytes): (&'static str, T)) -> Self {
Self::Bytes(uri.into(), bytes.into())
Self::Bytes {
uri: uri.into(),
bytes: bytes.into(),
}
}
}

impl<T: Into<Bytes>> From<(Cow<'static, str>, T)> for ImageSource<'static> {
#[inline]
fn from((uri, bytes): (Cow<'static, str>, T)) -> Self {
Self::Bytes(uri, bytes.into())
Self::Bytes {
uri,
bytes: bytes.into(),
}
}
}

impl<T: Into<Bytes>> From<(String, T)> for ImageSource<'static> {
#[inline]
fn from((uri, bytes): (String, T)) -> Self {
Self::Bytes(uri.into(), bytes.into())
Self::Bytes {
uri: uri.into(),
bytes: bytes.into(),
}
}
}

Expand Down
Loading