Rename ImageReference to ImageInner and make Immage.0 private

This commit is contained in:
Olivier Goffart 2021-05-28 16:17:42 +02:00 committed by Olivier Goffart
parent 8e44ac2351
commit 142a8dc185
14 changed files with 68 additions and 65 deletions

View file

@ -43,7 +43,7 @@ public:
} }
private: private:
using Tag = cbindgen_private::types::ImageReference::Tag; using Tag = cbindgen_private::types::ImageInner::Tag;
using Data = cbindgen_private::types::Image; using Data = cbindgen_private::types::Image;
Data data; Data data;
}; };

View file

@ -11,7 +11,7 @@ use core::cell::RefCell;
use neon::prelude::*; use neon::prelude::*;
use rand::RngCore; use rand::RngCore;
use sixtyfps_compilerlib::langtype::Type; use sixtyfps_compilerlib::langtype::Type;
use sixtyfps_corelib::{ImageReference, SharedVector}; use sixtyfps_corelib::{ImageInner, SharedVector};
mod js_model; mod js_model;
mod persistent_context; mod persistent_context;
@ -247,10 +247,12 @@ fn to_js_value<'cx>(
Value::Number(n) => JsNumber::new(cx, n).as_value(cx), Value::Number(n) => JsNumber::new(cx, n).as_value(cx),
Value::String(s) => JsString::new(cx, s.as_str()).as_value(cx), Value::String(s) => JsString::new(cx, s.as_str()).as_value(cx),
Value::Bool(b) => JsBoolean::new(cx, b).as_value(cx), Value::Bool(b) => JsBoolean::new(cx, b).as_value(cx),
Value::Image(r) => match r.0 { Value::Image(r) => match (&r).into() {
ImageReference::None => JsUndefined::new().as_value(cx), &ImageInner::None => JsUndefined::new().as_value(cx),
ImageReference::AbsoluteFilePath(path) => JsString::new(cx, path.as_str()).as_value(cx), &ImageInner::AbsoluteFilePath(ref path) => {
ImageReference::EmbeddedData { .. } | ImageReference::EmbeddedRgbaImage { .. } => { JsString::new(cx, path.as_str()).as_value(cx)
}
&ImageInner::EmbeddedData { .. } | &ImageInner::EmbeddedRgbaImage { .. } => {
JsNull::new().as_value(cx) JsNull::new().as_value(cx)
} // TODO: maybe pass around node buffers? } // TODO: maybe pass around node buffers?
}, },

View file

@ -226,7 +226,7 @@ pub mod re_exports {
init_component_items, Component, ComponentRefPin, ComponentVTable, init_component_items, Component, ComponentRefPin, ComponentVTable,
}; };
pub use sixtyfps_corelib::graphics::{ pub use sixtyfps_corelib::graphics::{
Brush, GradientStop, Image, ImageReference, LinearGradientBrush, PathArcTo, PathCubicTo, Brush, GradientStop, Image, ImageInner, LinearGradientBrush, PathArcTo, PathCubicTo,
PathData, PathElement, PathEvent, PathLineTo, PathMoveTo, PathQuadraticTo, Point, Rect, PathData, PathElement, PathEvent, PathLineTo, PathMoveTo, PathQuadraticTo, Point, Rect,
Size, Size,
}; };

View file

@ -1343,8 +1343,8 @@ fn compile_expression(expr: &Expression, component: &Rc<Component>) -> TokenStre
crate::expression_tree::ImageReference::EmbeddedData(resource_id) => { crate::expression_tree::ImageReference::EmbeddedData(resource_id) => {
let symbol = format_ident!("SFPS_EMBEDDED_RESOURCE_{}", resource_id); let symbol = format_ident!("SFPS_EMBEDDED_RESOURCE_{}", resource_id);
quote!( quote!(
sixtyfps::re_exports::Image( sixtyfps::re_exports::Image::from(
sixtyfps::re_exports::ImageReference::EmbeddedData(#symbol.into()) sixtyfps::re_exports::ImageInner::EmbeddedData(#symbol.into())
) )
) )
} }

View file

@ -16,7 +16,7 @@ use crate::{SharedString, SharedVector};
/// is necessary before they can be used. /// is necessary before they can be used.
#[derive(Clone, PartialEq, Debug)] #[derive(Clone, PartialEq, Debug)]
#[repr(u8)] #[repr(u8)]
pub enum ImageReference { pub enum ImageInner {
/// A resource that does not represent any data. /// A resource that does not represent any data.
None, None,
/// A resource that points to a file in the file system /// A resource that points to a file in the file system
@ -29,9 +29,15 @@ pub enum ImageReference {
EmbeddedRgbaImage { width: u32, height: u32, data: SharedVector<u32> }, EmbeddedRgbaImage { width: u32, height: u32, data: SharedVector<u32> },
} }
impl Default for ImageReference { impl Default for ImageInner {
fn default() -> Self { fn default() -> Self {
ImageReference::None ImageInner::None
}
}
impl<'a> From<&'a Image> for &'a ImageInner {
fn from(other: &'a Image) -> Self {
&other.0
} }
} }
@ -41,14 +47,14 @@ pub struct LoadImageError(());
/// An image type that can be displayed by the Image element /// An image type that can be displayed by the Image element
#[repr(transparent)] #[repr(transparent)]
#[derive(Default, Clone, Debug, PartialEq)] #[derive(Default, Clone, Debug, PartialEq, derive_more::From)]
// FIXME: the inner should be private // FIXME: the inner should be private
pub struct Image(pub ImageReference); pub struct Image(ImageInner);
impl Image { impl Image {
/// Load an Image from a path to a file containing an image /// Load an Image from a path to a file containing an image
pub fn load_from_path(path: &std::path::Path) -> Result<Self, LoadImageError> { pub fn load_from_path(path: &std::path::Path) -> Result<Self, LoadImageError> {
Ok(Image(ImageReference::AbsoluteFilePath(path.to_str().ok_or(LoadImageError(()))?.into()))) Ok(Image(ImageInner::AbsoluteFilePath(path.to_str().ok_or(LoadImageError(()))?.into())))
} }
/* /*
/// Create an image from argb pixels. /// Create an image from argb pixels.

View file

@ -72,7 +72,7 @@ impl Item for ImageItem {
} }
fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo { fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo {
let natural_size = window.0.image_size(&self.source().0); let natural_size = window.0.image_size((&self.source()).into());
LayoutInfo { LayoutInfo {
preferred_width: natural_size.width, preferred_width: natural_size.width,
preferred_height: natural_size.height, preferred_height: natural_size.height,
@ -143,7 +143,7 @@ impl Item for ClippedImage {
} }
fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo { fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo {
let natural_size = window.0.image_size(&self.source().0); let natural_size = window.0.image_size((&self.source()).into());
LayoutInfo { LayoutInfo {
preferred_width: natural_size.width, preferred_width: natural_size.width,
preferred_height: natural_size.height, preferred_height: natural_size.height,

View file

@ -49,7 +49,7 @@ pub use string::SharedString;
pub use sharedvector::SharedVector; pub use sharedvector::SharedVector;
#[doc(inline)] #[doc(inline)]
pub use graphics::ImageReference; pub use graphics::ImageInner;
#[doc(inline)] #[doc(inline)]
pub use properties::Property; pub use properties::Property;

View file

@ -15,7 +15,7 @@ use crate::input::{KeyEvent, MouseEvent, MouseInputState, TextCursorBlinker};
use crate::items::{ItemRc, ItemRef, ItemWeak}; use crate::items::{ItemRc, ItemRef, ItemWeak};
use crate::properties::PropertyTracker; use crate::properties::PropertyTracker;
use crate::slice::Slice; use crate::slice::Slice;
use crate::ImageReference; use crate::ImageInner;
use crate::{ use crate::{
component::{ComponentRc, ComponentWeak}, component::{ComponentRc, ComponentWeak},
SharedString, SharedString,
@ -69,7 +69,7 @@ pub trait PlatformWindow {
/// Return the size of the image referenced by the specified resource, multiplied by the window /// Return the size of the image referenced by the specified resource, multiplied by the window
/// scale factor. /// scale factor.
fn image_size(&self, source: &ImageReference) -> crate::graphics::Size; fn image_size(&self, source: &ImageInner) -> crate::graphics::Size;
/// Return self as any so the backend can upcast /// Return self as any so the backend can upcast
fn as_any(&self) -> &dyn core::any::Any; fn as_any(&self) -> &dyn core::any::Any;

View file

@ -507,7 +507,7 @@ impl PlatformWindow for GraphicsWindow {
)) ))
} }
fn image_size(&self, source: &ImageReference) -> sixtyfps_corelib::graphics::Size { fn image_size(&self, source: &ImageInner) -> sixtyfps_corelib::graphics::Size {
match &*self.map_state.borrow() { match &*self.map_state.borrow() {
GraphicsWindowBackendState::Unmapped => { GraphicsWindowBackendState::Unmapped => {
// Temporary: Register this internal property to notify the caller when // Temporary: Register this internal property to notify the caller when

View file

@ -11,7 +11,7 @@ LICENSE END */
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use sixtyfps_corelib::{graphics::Size, slice::Slice, ImageReference, Property, SharedString}; use sixtyfps_corelib::{graphics::Size, slice::Slice, ImageInner, Property, SharedString};
use super::{CanvasRc, GLItemRenderer, GLRendererData, ItemGraphicsCacheEntry}; use super::{CanvasRc, GLItemRenderer, GLRendererData, ItemGraphicsCacheEntry};
@ -115,15 +115,12 @@ impl CachedImage {
Self(RefCell::new(ImageData::SVG(tree))) Self(RefCell::new(ImageData::SVG(tree)))
} }
pub fn new_from_resource( pub fn new_from_resource(resource: &ImageInner, renderer: &GLRendererData) -> Option<Rc<Self>> {
resource: &ImageReference,
renderer: &GLRendererData,
) -> Option<Rc<Self>> {
match resource { match resource {
ImageReference::None => None, ImageInner::None => None,
ImageReference::AbsoluteFilePath(path) => Self::new_from_path(path, renderer), ImageInner::AbsoluteFilePath(path) => Self::new_from_path(path, renderer),
ImageReference::EmbeddedData(data) => Self::new_from_data(data).map(Rc::new), ImageInner::EmbeddedData(data) => Self::new_from_data(data).map(Rc::new),
ImageReference::EmbeddedRgbaImage { .. } => todo!(), ImageInner::EmbeddedRgbaImage { .. } => todo!(),
} }
} }

View file

@ -31,7 +31,7 @@ use sixtyfps_corelib::items::{
use sixtyfps_corelib::properties::Property; use sixtyfps_corelib::properties::Property;
use sixtyfps_corelib::window::ComponentWindow; use sixtyfps_corelib::window::ComponentWindow;
use sixtyfps_corelib::{ImageReference, SharedString}; use sixtyfps_corelib::{ImageInner, SharedString};
mod graphics_window; mod graphics_window;
use graphics_window::*; use graphics_window::*;
@ -53,19 +53,19 @@ enum ImageCacheKey {
} }
impl ImageCacheKey { impl ImageCacheKey {
fn new(resource: &ImageReference) -> Option<Self> { fn new(resource: &ImageInner) -> Option<Self> {
Some(match resource { Some(match resource {
ImageReference::None => return None, ImageInner::None => return None,
ImageReference::AbsoluteFilePath(path) => { ImageInner::AbsoluteFilePath(path) => {
if path.is_empty() { if path.is_empty() {
return None; return None;
} }
Self::Path(path.to_string()) Self::Path(path.to_string())
} }
ImageReference::EmbeddedData(data) => { ImageInner::EmbeddedData(data) => {
Self::EmbeddedData(by_address::ByAddress(data.as_slice())) Self::EmbeddedData(by_address::ByAddress(data.as_slice()))
} }
ImageReference::EmbeddedRgbaImage { .. } => return None, ImageInner::EmbeddedRgbaImage { .. } => return None,
}) })
} }
} }
@ -364,7 +364,7 @@ impl GLRendererData {
} }
// Try to load the image the given resource points to // Try to load the image the given resource points to
fn load_image_resource(&self, resource: &ImageReference) -> Option<Rc<CachedImage>> { fn load_image_resource(&self, resource: &ImageInner) -> Option<Rc<CachedImage>> {
let cache_key = ImageCacheKey::new(resource)?; let cache_key = ImageCacheKey::new(resource)?;
self.lookup_image_in_cache_or_create(cache_key, || { self.lookup_image_in_cache_or_create(cache_key, || {
@ -474,7 +474,7 @@ impl GLRenderer {
/// Returns the size of image referenced by the specified resource. These are image pixels, not adjusted /// Returns the size of image referenced by the specified resource. These are image pixels, not adjusted
/// to the window scale factor. /// to the window scale factor.
fn image_size(&self, source: &ImageReference) -> sixtyfps_corelib::graphics::Size { fn image_size(&self, source: &ImageInner) -> sixtyfps_corelib::graphics::Size {
self.shared_data self.shared_data
.load_image_resource(source) .load_image_resource(source)
.and_then(|image| image.size()) .and_then(|image| image.size())
@ -1376,7 +1376,7 @@ impl GLItemRenderer {
.borrow_mut() .borrow_mut()
.load_item_graphics_cache_with_function(item_cache, || { .load_item_graphics_cache_with_function(item_cache, || {
self.shared_data self.shared_data
.load_image_resource(&source_property.get().0) .load_image_resource((&source_property.get()).into())
.and_then(|cached_image| { .and_then(|cached_image| {
cached_image.as_renderable( cached_image.as_renderable(
// The condition at the entry of the function ensures that width/height are positive // The condition at the entry of the function ensures that width/height are positive

View file

@ -17,7 +17,7 @@ use sixtyfps_corelib::items::{self, FillRule, ItemRef, TextOverflow, TextWrap};
use sixtyfps_corelib::slice::Slice; use sixtyfps_corelib::slice::Slice;
use sixtyfps_corelib::window::PlatformWindow; use sixtyfps_corelib::window::PlatformWindow;
use sixtyfps_corelib::{component::ComponentRc, SharedString}; use sixtyfps_corelib::{component::ComponentRc, SharedString};
use sixtyfps_corelib::{ImageReference, PathData, Property}; use sixtyfps_corelib::{ImageInner, PathData, Property};
use std::cell::RefCell; use std::cell::RefCell;
use std::pin::Pin; use std::pin::Pin;
@ -719,15 +719,15 @@ impl ItemRenderer for QtItemRenderer<'_> {
} }
fn load_image_from_resource( fn load_image_from_resource(
resource: &ImageReference, resource: &ImageInner,
source_size: Option<qttypes::QSize>, source_size: Option<qttypes::QSize>,
image_fit: ImageFit, image_fit: ImageFit,
) -> Option<qttypes::QPixmap> { ) -> Option<qttypes::QPixmap> {
let (is_path, data) = match resource { let (is_path, data) = match resource {
ImageReference::None => return None, ImageInner::None => return None,
ImageReference::AbsoluteFilePath(path) => (true, qttypes::QByteArray::from(path.as_str())), ImageInner::AbsoluteFilePath(path) => (true, qttypes::QByteArray::from(path.as_str())),
ImageReference::EmbeddedData(data) => (false, qttypes::QByteArray::from(data.as_slice())), ImageInner::EmbeddedData(data) => (false, qttypes::QByteArray::from(data.as_slice())),
ImageReference::EmbeddedRgbaImage { .. } => todo!(), ImageInner::EmbeddedRgbaImage { .. } => todo!(),
}; };
let size_requested = is_svg(resource) && source_size.is_some(); let size_requested = is_svg(resource) && source_size.is_some();
let source_size = source_size.unwrap_or_default(); let source_size = source_size.unwrap_or_default();
@ -807,12 +807,12 @@ fn adjust_to_image_fit(
} }
/// Return true if this image is a SVG that is scalable /// Return true if this image is a SVG that is scalable
fn is_svg(resource: &ImageReference) -> bool { fn is_svg(resource: &ImageInner) -> bool {
match resource { match resource {
ImageReference::None => false, ImageInner::None => false,
ImageReference::AbsoluteFilePath(path) => path.as_str().ends_with(".svg"), ImageInner::AbsoluteFilePath(path) => path.as_str().ends_with(".svg"),
ImageReference::EmbeddedData(data) => data.starts_with(b"<svg"), ImageInner::EmbeddedData(data) => data.starts_with(b"<svg"),
ImageReference::EmbeddedRgbaImage { .. } => false, ImageInner::EmbeddedRgbaImage { .. } => false,
} }
} }
@ -851,9 +851,8 @@ impl QtItemRenderer<'_> {
None None
}; };
load_image_from_resource(&source_property.get().0, source_size, image_fit).map_or( load_image_from_resource((&source_property.get()).into(), source_size, image_fit)
QtRenderingCacheItem::Invalid, .map_or(QtRenderingCacheItem::Invalid, |mut pixmap: qttypes::QPixmap| {
|mut pixmap: qttypes::QPixmap| {
let colorize = colorize_property.map_or(Brush::default(), |c| c.get()); let colorize = colorize_property.map_or(Brush::default(), |c| c.get());
if !colorize.is_transparent() { if !colorize.is_transparent() {
let brush: QBrush = colorize.into(); let brush: QBrush = colorize.into();
@ -864,8 +863,7 @@ impl QtItemRenderer<'_> {
}); });
} }
QtRenderingCacheItem::Pixmap(pixmap) QtRenderingCacheItem::Pixmap(pixmap)
}, })
)
}); });
let pixmap: &qttypes::QPixmap = match &cached { let pixmap: &qttypes::QPixmap = match &cached {
QtRenderingCacheItem::Pixmap(pixmap) => pixmap, QtRenderingCacheItem::Pixmap(pixmap) => pixmap,
@ -1204,7 +1202,7 @@ impl PlatformWindow for QtWindow {
Box::new(get_font(unresolved_font_request_getter().merge(&self.default_font_properties()))) Box::new(get_font(unresolved_font_request_getter().merge(&self.default_font_properties())))
} }
fn image_size(&self, source: &ImageReference) -> sixtyfps_corelib::graphics::Size { fn image_size(&self, source: &ImageInner) -> sixtyfps_corelib::graphics::Size {
load_image_from_resource(source, None, ImageFit::fill) load_image_from_resource(source, None, ImageFit::fill)
.map(|img| { .map(|img| {
let qsize = img.size(); let qsize = img.size();

View file

@ -21,7 +21,7 @@ use sixtyfps_corelib::component::ComponentRc;
use sixtyfps_corelib::graphics::{FontMetrics, Size}; use sixtyfps_corelib::graphics::{FontMetrics, Size};
use sixtyfps_corelib::slice::Slice; use sixtyfps_corelib::slice::Slice;
use sixtyfps_corelib::window::{ComponentWindow, PlatformWindow, Window}; use sixtyfps_corelib::window::{ComponentWindow, PlatformWindow, Window};
use sixtyfps_corelib::{ImageReference, Property}; use sixtyfps_corelib::{ImageInner, Property};
use std::path::Path; use std::path::Path;
use std::pin::Pin; use std::pin::Pin;
use std::rc::Rc; use std::rc::Rc;
@ -125,19 +125,19 @@ impl PlatformWindow for TestingWindow {
Box::new(TestingFontMetrics::default()) Box::new(TestingFontMetrics::default())
} }
fn image_size(&self, source: &ImageReference) -> Size { fn image_size(&self, source: &ImageInner) -> Size {
match source { match source {
ImageReference::None => Default::default(), ImageInner::None => Default::default(),
ImageReference::EmbeddedRgbaImage { width, height, .. } => { ImageInner::EmbeddedRgbaImage { width, height, .. } => {
Size::new(*width as _, *height as _) Size::new(*width as _, *height as _)
} }
ImageReference::AbsoluteFilePath(path) => image::open(Path::new(path.as_str())) ImageInner::AbsoluteFilePath(path) => image::open(Path::new(path.as_str()))
.map(|img| { .map(|img| {
let dim = img.dimensions(); let dim = img.dimensions();
Size::new(dim.0 as _, dim.1 as _) Size::new(dim.0 as _, dim.1 as _)
}) })
.unwrap_or_default(), .unwrap_or_default(),
ImageReference::EmbeddedData(data) => image::load_from_memory(data.as_slice()) ImageInner::EmbeddedData(data) => image::load_from_memory(data.as_slice())
.map(|img| { .map(|img| {
let dim = img.dimensions(); let dim = img.dimensions();
Size::new(dim.0 as _, dim.1 as _) Size::new(dim.0 as _, dim.1 as _)

View file

@ -109,7 +109,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
config.export.exclude = [ config.export.exclude = [
"SharedString", "SharedString",
"SharedVector", "SharedVector",
"ImageReference", "ImageInner",
"Image", "Image",
"Color", "Color",
"PathData", "PathData",
@ -180,7 +180,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> {
.write_to_file(include_dir.join("sixtyfps_properties_internal.h")); .write_to_file(include_dir.join("sixtyfps_properties_internal.h"));
for (rust_types, extra_excluded_types, internal_header) in [ for (rust_types, extra_excluded_types, internal_header) in [
(vec!["ImageReference", "Image"], vec![], "sixtyfps_image_internal.h"), (vec!["ImageInner", "Image"], vec![], "sixtyfps_image_internal.h"),
( (
vec!["Color", "sixtyfps_color_brighter", "sixtyfps_color_darker"], vec!["Color", "sixtyfps_color_brighter", "sixtyfps_color_darker"],
vec![], vec![],