From 0b3fecf300382a9ab93c4927739e4745d94d06ed Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 28 May 2021 12:13:49 +0200 Subject: [PATCH] WIP: API to expose image loading from C++ and Rust --- api/sixtyfps-cpp/include/sixtyfps_image.h | 25 +++++-- api/sixtyfps-node/native/lib.rs | 8 ++- api/sixtyfps-rs/lib.rs | 6 +- sixtyfps_compiler/generator/cpp.rs | 6 +- sixtyfps_compiler/generator/rust.rs | 12 ++-- sixtyfps_runtime/corelib/graphics.rs | 27 +------- sixtyfps_runtime/corelib/graphics/image.rs | 65 +++++++++++++++++++ sixtyfps_runtime/corelib/items/image.rs | 12 ++-- sixtyfps_runtime/corelib/rtti.rs | 2 +- sixtyfps_runtime/interpreter/api.rs | 9 ++- .../interpreter/dynamic_component.rs | 3 +- sixtyfps_runtime/interpreter/eval.rs | 13 ++-- sixtyfps_runtime/rendering_backends/gl/lib.rs | 10 +-- .../rendering_backends/qt/qt_window.rs | 6 +- xtask/src/cbindgen.rs | 4 +- 15 files changed, 140 insertions(+), 68 deletions(-) create mode 100644 sixtyfps_runtime/corelib/graphics/image.rs diff --git a/api/sixtyfps-cpp/include/sixtyfps_image.h b/api/sixtyfps-cpp/include/sixtyfps_image.h index 0380d5e52..f31e4e775 100644 --- a/api/sixtyfps-cpp/include/sixtyfps_image.h +++ b/api/sixtyfps-cpp/include/sixtyfps_image.h @@ -11,26 +11,39 @@ LICENSE END */ #include #include "sixtyfps_image_internal.h" #include "sixtyfps_string.h" +#include "sixtyfps_sharedvector.h" namespace sixtyfps { -struct ImageReference +/// An image type that can be displayed by the Image element +struct Image { public: - ImageReference() : data(Data::None()) { } - ImageReference(const SharedString &file_path) : data(Data::AbsoluteFilePath(file_path)) { } + Image() : data(Data::None()) { } - friend bool operator==(const ImageReference &a, const ImageReference &b) { + static Image load_from_path(const SharedString &file_path) { + Image img; + img.data = Data::AbsoluteFilePath(file_path); + return img; + } + + static Image load_from_argb(int width, int height, const SharedVector &data) { + Image img; + img.data = Data::EmbeddedRgbaImage(width, height, data); + return img; + } + + friend bool operator==(const Image &a, const Image &b) { return a.data == b.data; } - friend bool operator!=(const ImageReference &a, const ImageReference &b) { + friend bool operator!=(const Image &a, const Image &b) { return a.data != b.data; } private: using Tag = cbindgen_private::types::ImageReference::Tag; - using Data = cbindgen_private::types::ImageReference; + using Data = cbindgen_private::types::Image; Data data; }; diff --git a/api/sixtyfps-node/native/lib.rs b/api/sixtyfps-node/native/lib.rs index 8b45bad87..1be3115df 100644 --- a/api/sixtyfps-node/native/lib.rs +++ b/api/sixtyfps-node/native/lib.rs @@ -195,7 +195,11 @@ fn to_eval_value<'cx>( } }, Type::Image => { - Ok(Value::Image(ImageReference::AbsoluteFilePath(val.to_string(cx)?.value().into()))) + let path = val.to_string(cx)?.value(); + Ok(Value::Image( + sixtyfps_corelib::graphics::Image::load_from_path(std::path::Path::new(&path)) + .or_else(|_| cx.throw_error(format!("cannot load image {:?}", path)))?, + )) } Type::Bool => Ok(Value::Bool(val.downcast_or_throw::(cx)?.value())), Type::Struct { fields, .. } => { @@ -243,7 +247,7 @@ fn to_js_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::Bool(b) => JsBoolean::new(cx, b).as_value(cx), - Value::Image(r) => match r { + Value::Image(r) => match r.0 { ImageReference::None => JsUndefined::new().as_value(cx), ImageReference::AbsoluteFilePath(path) => JsString::new(cx, path.as_str()).as_value(cx), ImageReference::EmbeddedData { .. } | ImageReference::EmbeddedRgbaImage { .. } => { diff --git a/api/sixtyfps-rs/lib.rs b/api/sixtyfps-rs/lib.rs index ec49fab8e..a4ff21607 100644 --- a/api/sixtyfps-rs/lib.rs +++ b/api/sixtyfps-rs/lib.rs @@ -224,8 +224,9 @@ pub mod re_exports { init_component_items, Component, ComponentRefPin, ComponentVTable, }; pub use sixtyfps_corelib::graphics::{ - Brush, GradientStop, LinearGradientBrush, PathArcTo, PathCubicTo, PathData, PathElement, - PathEvent, PathLineTo, PathMoveTo, PathQuadraticTo, Point, Rect, Size, + Brush, GradientStop, Image, ImageReference, LinearGradientBrush, PathArcTo, PathCubicTo, + PathData, PathElement, PathEvent, PathLineTo, PathMoveTo, PathQuadraticTo, Point, Rect, + Size, }; pub use sixtyfps_corelib::input::{ FocusEvent, InputEventResult, KeyEvent, KeyEventResult, KeyboardModifiers, MouseEvent, @@ -242,7 +243,6 @@ pub mod re_exports { pub use sixtyfps_corelib::window::ComponentWindow; pub use sixtyfps_corelib::Color; pub use sixtyfps_corelib::ComponentVTable_static; - pub use sixtyfps_corelib::ImageReference; pub use sixtyfps_corelib::SharedString; pub use sixtyfps_corelib::SharedVector; pub use sixtyfps_rendering_backend_default::native_widgets::*; diff --git a/sixtyfps_compiler/generator/cpp.rs b/sixtyfps_compiler/generator/cpp.rs index 3266dbbff..3b01c648e 100644 --- a/sixtyfps_compiler/generator/cpp.rs +++ b/sixtyfps_compiler/generator/cpp.rs @@ -255,7 +255,7 @@ impl CppType for Type { } Type::Array(i) => Some(format!("std::shared_ptr>", i.cpp_type()?)), - Type::Image => Some("sixtyfps::ImageReference".to_owned()), + Type::Image => Some("sixtyfps::Image".to_owned()), Type::Builtin(elem) => elem.native_class.cpp_type.clone(), Type::Enumeration(enumeration) => Some(format!("sixtyfps::{}", enumeration.name)), Type::Brush => Some("sixtyfps::Brush".to_owned()), @@ -1613,8 +1613,8 @@ fn compile_expression( } Expression::ImageReference(resource_ref) => { match resource_ref { - crate::expression_tree::ImageReference::None => format!(r#"sixtyfps::ImageReference()"#), - crate::expression_tree::ImageReference::AbsolutePath(path) => format!(r#"sixtyfps::ImageReference(sixtyfps::SharedString(u8"{}"))"#, escape_string(path.as_str())), + crate::expression_tree::ImageReference::None => format!(r#"sixtyfps::Image()"#), + crate::expression_tree::ImageReference::AbsolutePath(path) => format!(r#"sixtyfps::Image::load_from_path(sixtyfps::SharedString(u8"{}"))"#, escape_string(path.as_str())), crate::expression_tree::ImageReference::EmbeddedData(_) => unimplemented!("The C++ generator does not support resource embedding yet") } } diff --git a/sixtyfps_compiler/generator/rust.rs b/sixtyfps_compiler/generator/rust.rs index 71be5f2da..c77b15dbd 100644 --- a/sixtyfps_compiler/generator/rust.rs +++ b/sixtyfps_compiler/generator/rust.rs @@ -39,7 +39,7 @@ fn rust_type(ty: &Type) -> Option { Type::LogicalLength => Some(quote!(f32)), Type::Percent => Some(quote!(f32)), Type::Bool => Some(quote!(bool)), - Type::Image => Some(quote!(sixtyfps::re_exports::ImageReference)), + Type::Image => Some(quote!(sixtyfps::re_exports::Image)), Type::Struct { fields, name: None, .. } => { let elem = fields.values().map(|v| rust_type(v)).collect::>>()?; // This will produce a tuple @@ -1335,14 +1335,18 @@ fn compile_expression(expr: &Expression, component: &Rc) -> TokenStre Expression::ImageReference(resource_ref) => { match resource_ref { crate::expression_tree::ImageReference::None => { - quote!(sixtyfps::re_exports::ImageReference::None) + quote!(sixtyfps::re_exports::Image::default()) } crate::expression_tree::ImageReference::AbsolutePath(path) => { - quote!(sixtyfps::re_exports::ImageReference::AbsoluteFilePath(sixtyfps::re_exports::SharedString::from(#path))) + quote!(sixtyfps::re_exports::Image::load_from_path(sixtyfps::re_exports::SharedString::from(#path))) }, crate::expression_tree::ImageReference::EmbeddedData(resource_id) => { let symbol = format_ident!("SFPS_EMBEDDED_RESOURCE_{}", resource_id); - quote!(sixtyfps::re_exports::ImageReference::EmbeddedData(#symbol.into())) + quote!( + sixtyfps::re_exports::Image( + sixtyfps::re_exports::ImageReference::EmbeddedData(#symbol.into()) + ) + ) } } } diff --git a/sixtyfps_runtime/corelib/graphics.rs b/sixtyfps_runtime/corelib/graphics.rs index 8c6b812ae..4ae980d32 100644 --- a/sixtyfps_runtime/corelib/graphics.rs +++ b/sixtyfps_runtime/corelib/graphics.rs @@ -42,31 +42,8 @@ pub use path::*; mod brush; pub use brush::*; -/// A resource is a reference to binary data, for example images. They can be accessible on the file -/// system or embedded in the resulting binary. Or they might be URLs to a web server and a downloaded -/// is necessary before they can be used. -/// -/// TODO! If we want to make this type public API, we should not make it an enum, but an opaque type instead -#[derive(Clone, PartialEq, Debug)] -#[repr(u8)] -pub enum ImageReference { - /// A resource that does not represent any data. - None, - /// A resource that points to a file in the file system - AbsoluteFilePath(crate::SharedString), - /// A resource that is embedded in the program and accessible via pointer - /// The format is the same as in a file - EmbeddedData(super::slice::Slice<'static, u8>), - /// Raw ARGB - #[allow(missing_docs)] - EmbeddedRgbaImage { width: u32, height: u32, data: super::sharedvector::SharedVector }, -} - -impl Default for ImageReference { - fn default() -> Self { - ImageReference::None - } -} +mod image; +pub use self::image::*; /// CachedGraphicsData allows the graphics backend to store an arbitrary piece of data associated with /// an item, which is typically computed by accessing properties. The dependency_tracker is used to allow diff --git a/sixtyfps_runtime/corelib/graphics/image.rs b/sixtyfps_runtime/corelib/graphics/image.rs new file mode 100644 index 000000000..fe8b75f99 --- /dev/null +++ b/sixtyfps_runtime/corelib/graphics/image.rs @@ -0,0 +1,65 @@ +/* LICENSE BEGIN + This file is part of the SixtyFPS Project -- https://sixtyfps.io + Copyright (c) 2020 Olivier Goffart + Copyright (c) 2020 Simon Hausmann + + SPDX-License-Identifier: GPL-3.0-only + This file is also available under commercial licensing terms. + Please contact info@sixtyfps.io for more information. +LICENSE END */ + +use crate::slice::Slice; +use crate::{SharedString, SharedVector}; + +/// A resource is a reference to binary data, for example images. They can be accessible on the file +/// system or embedded in the resulting binary. Or they might be URLs to a web server and a downloaded +/// is necessary before they can be used. +#[derive(Clone, PartialEq, Debug)] +#[repr(u8)] +pub enum ImageReference { + /// A resource that does not represent any data. + None, + /// A resource that points to a file in the file system + AbsoluteFilePath(SharedString), + /// A resource that is embedded in the program and accessible via pointer + /// The format is the same as in a file + EmbeddedData(Slice<'static, u8>), + /// Raw ARGB + #[allow(missing_docs)] + EmbeddedRgbaImage { width: u32, height: u32, data: SharedVector }, +} + +impl Default for ImageReference { + fn default() -> Self { + ImageReference::None + } +} + +/// Error generated if an image cannot be loaded for any reasons. +#[derive(Default, Debug, PartialEq)] +pub struct LoadImageError(()); + +/// An image type that can be displayed by the Image element +#[repr(transparent)] +#[derive(Default, Clone, Debug, PartialEq)] +// FIXME: the inner should be private +pub struct Image(pub ImageReference); + +impl Image { + /// Create an Image from a path to a file containing an image + pub fn load_from_path(path: &std::path::Path) -> Result { + Ok(Image(ImageReference::AbsoluteFilePath(path.to_str().ok_or(LoadImageError(()))?.into()))) + } + /// Create an image from argb pixels + pub fn load_from_argb( + width: u32, + height: u32, + data: SharedVector, + ) -> Result { + if data.len() != width as usize * height as usize { + Err(LoadImageError(())) + } else { + Ok(Image(ImageReference::EmbeddedRgbaImage { width, height, data })) + } + } +} diff --git a/sixtyfps_runtime/corelib/items/image.rs b/sixtyfps_runtime/corelib/items/image.rs index f85ee98d2..107b0086f 100644 --- a/sixtyfps_runtime/corelib/items/image.rs +++ b/sixtyfps_runtime/corelib/items/image.rs @@ -20,7 +20,7 @@ When adding an item or a property, it needs to be kept in sync with different pl - Don't forget to update the documentation */ use super::{Item, ItemConsts, ItemRc}; -use crate::graphics::{ImageReference, Rect}; +use crate::graphics::Rect; use crate::input::{ FocusEvent, InputEventFilterResult, InputEventResult, KeyEvent, KeyEventResult, MouseEvent, }; @@ -55,7 +55,7 @@ impl Default for ImageFit { #[pin] /// The implementation of the `Image` element pub struct ImageItem { - pub source: Property, + pub source: Property, pub x: Property, pub y: Property, pub width: Property, @@ -72,7 +72,7 @@ impl Item for ImageItem { } fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo { - let natural_size = window.0.image_size(&self.source()); + let natural_size = window.0.image_size(&self.source().0); LayoutInfo { preferred_width: natural_size.width, preferred_height: natural_size.height, @@ -121,7 +121,7 @@ impl ItemConsts for ImageItem { #[pin] /// The implementation of the `ClippedImage` element pub struct ClippedImage { - pub source: Property, + pub source: Property, pub x: Property, pub y: Property, pub width: Property, @@ -143,7 +143,7 @@ impl Item for ClippedImage { } fn layouting_info(self: Pin<&Self>, window: &ComponentWindow) -> LayoutInfo { - let natural_size = window.0.image_size(&self.source()); + let natural_size = window.0.image_size(&self.source().0); LayoutInfo { preferred_width: natural_size.width, preferred_height: natural_size.height, @@ -185,4 +185,4 @@ impl ItemConsts for ClippedImage { ClippedImage, CachedRenderingData, > = ClippedImage::FIELD_OFFSETS.cached_rendering_data.as_unpinned_projection(); -} +} \ No newline at end of file diff --git a/sixtyfps_runtime/corelib/rtti.rs b/sixtyfps_runtime/corelib/rtti.rs index cc4df1662..b68c6f8d3 100644 --- a/sixtyfps_runtime/corelib/rtti.rs +++ b/sixtyfps_runtime/corelib/rtti.rs @@ -32,7 +32,7 @@ declare_ValueType![ f32, f64, crate::SharedString, - crate::ImageReference, + crate::graphics::Image, crate::Color, crate::PathData, crate::animations::EasingCurve, diff --git a/sixtyfps_runtime/interpreter/api.rs b/sixtyfps_runtime/interpreter/api.rs index a49d8e7eb..a40efebc6 100644 --- a/sixtyfps_runtime/interpreter/api.rs +++ b/sixtyfps_runtime/interpreter/api.rs @@ -10,7 +10,8 @@ LICENSE END */ use core::convert::TryInto; use sixtyfps_compilerlib::langtype::Type as LangType; -use sixtyfps_corelib::{Brush, ImageReference, PathData, SharedString, SharedVector}; +use sixtyfps_corelib::graphics::Image; +use sixtyfps_corelib::{Brush, PathData, SharedString, SharedVector}; use std::collections::HashMap; use std::iter::FromIterator; use std::path::{Path, PathBuf}; @@ -40,6 +41,8 @@ pub enum ValueType { Struct, /// Correspond to `brush` or `color` type in .60. For color, this is then a [`Brush::SolidColor`] Brush, + /// Correspond to `image` type in .60. + Image, /// The type is not a public type but something internal. Other = -1, } @@ -92,7 +95,7 @@ pub enum Value { Bool(bool), #[doc(hidden)] /// Correspond to the `image` type in .60 - Image(ImageReference), + Image(Image), /// An Array in the .60 language. Array(SharedVector), /// A more complex model which is not created by the interpreter itself (Value::Array can also be used for model) @@ -212,7 +215,7 @@ macro_rules! declare_value_conversion { declare_value_conversion!(Number => [u32, u64, i32, i64, f32, f64, usize, isize] ); declare_value_conversion!(String => [SharedString] ); declare_value_conversion!(Bool => [bool] ); -declare_value_conversion!(Image => [ImageReference] ); +declare_value_conversion!(Image => [Image] ); declare_value_conversion!(Struct => [Struct] ); declare_value_conversion!(Brush => [Brush] ); declare_value_conversion!(PathElements => [PathData]); diff --git a/sixtyfps_runtime/interpreter/dynamic_component.rs b/sixtyfps_runtime/interpreter/dynamic_component.rs index 414e9481a..665501622 100644 --- a/sixtyfps_runtime/interpreter/dynamic_component.rs +++ b/sixtyfps_runtime/interpreter/dynamic_component.rs @@ -18,7 +18,6 @@ use sixtyfps_compilerlib::object_tree::{Element, ElementRc}; use sixtyfps_compilerlib::*; use sixtyfps_compilerlib::{diagnostics::BuildDiagnostics, object_tree::PropertyDeclaration}; use sixtyfps_corelib::component::{Component, ComponentRef, ComponentRefPin, ComponentVTable}; -use sixtyfps_corelib::graphics::ImageReference; use sixtyfps_corelib::item_tree::{ ItemTreeNode, ItemVisitorRefMut, ItemVisitorVTable, TraversalOrder, VisitChildrenResult, }; @@ -750,7 +749,7 @@ pub(crate) fn generate_component<'id>( Type::Angle => animated_property_info::(), Type::PhysicalLength => animated_property_info::(), Type::LogicalLength => animated_property_info::(), - Type::Image => property_info::(), + Type::Image => property_info::(), Type::Bool => property_info::(), Type::Callback { .. } => { custom_callbacks.insert(name.clone(), builder.add_field_type::()); diff --git a/sixtyfps_runtime/interpreter/eval.rs b/sixtyfps_runtime/interpreter/eval.rs index 159341939..23ac68688 100644 --- a/sixtyfps_runtime/interpreter/eval.rs +++ b/sixtyfps_runtime/interpreter/eval.rs @@ -16,7 +16,7 @@ use corelib::graphics::{GradientStop, LinearGradientBrush, PathElement}; use corelib::items::{ItemRef, PropertyAnimation}; use corelib::rtti::AnimatedBindingKind; use corelib::window::ComponentWindow; -use corelib::{Brush, Color, ImageReference, PathData, SharedString, SharedVector}; +use corelib::{Brush, Color, PathData, SharedString, SharedVector}; use sixtyfps_compilerlib::expression_tree::{ BindingExpression, BuiltinFunction, EasingCurve, Expression, Path as ExprPath, PathElement as ExprPathElement, @@ -468,15 +468,18 @@ pub fn eval_expression(e: &Expression, local_context: &mut EvalLocalContext) -> } } Expression::ImageReference(resource_ref) => { - match resource_ref { + Value::Image(match resource_ref { sixtyfps_compilerlib::expression_tree::ImageReference::None => { - Value::Image(ImageReference::None) + Ok(Default::default()) } sixtyfps_compilerlib::expression_tree::ImageReference::AbsolutePath(path) => { - Value::Image(ImageReference::AbsoluteFilePath(path.into())) + corelib::graphics::Image::load_from_path(std::path::Path::new(path)) } sixtyfps_compilerlib::expression_tree::ImageReference::EmbeddedData(_) => panic!("Resource embedding is not supported by the interpreter") - } + }.unwrap_or_else(|_| { + eprintln!("Could not load image {:?}",resource_ref ); + Default::default() + })) } Expression::Condition { condition, true_expr, false_expr } => { match eval_expression(&**condition, local_context).try_into() diff --git a/sixtyfps_runtime/rendering_backends/gl/lib.rs b/sixtyfps_runtime/rendering_backends/gl/lib.rs index 848d1f1dd..7f203733a 100644 --- a/sixtyfps_runtime/rendering_backends/gl/lib.rs +++ b/sixtyfps_runtime/rendering_backends/gl/lib.rs @@ -22,7 +22,7 @@ use std::pin::Pin; use std::rc::Rc; use sixtyfps_corelib::graphics::{ - Brush, Color, FontRequest, ImageReference, IntRect, Point, Rect, RenderingCache, Size, + Brush, Color, FontRequest, Image, IntRect, Point, Rect, RenderingCache, Size, }; use sixtyfps_corelib::item_rendering::{CachedRenderingData, ItemRenderer}; use sixtyfps_corelib::items::{ @@ -30,7 +30,8 @@ use sixtyfps_corelib::items::{ }; use sixtyfps_corelib::properties::Property; use sixtyfps_corelib::window::ComponentWindow; -use sixtyfps_corelib::SharedString; + +use sixtyfps_corelib::{ImageReference, SharedString}; mod graphics_window; use graphics_window::*; @@ -241,6 +242,7 @@ impl OpenGLContext { (Self::Current(windowed_context), renderer) } + #[cfg(target_arch = "wasm32")] { use wasm_bindgen::JsCast; @@ -1353,7 +1355,7 @@ impl GLItemRenderer { fn draw_image_impl( &mut self, item_cache: &CachedRenderingData, - source_property: std::pin::Pin<&Property>, + source_property: std::pin::Pin<&Property>, source_clip_rect: IntRect, target_width: std::pin::Pin<&Property>, target_height: std::pin::Pin<&Property>, @@ -1374,7 +1376,7 @@ impl GLItemRenderer { .borrow_mut() .load_item_graphics_cache_with_function(item_cache, || { self.shared_data - .load_image_resource(&source_property.get()) + .load_image_resource(&source_property.get().0) .and_then(|cached_image| { cached_image.as_renderable( // The condition at the entry of the function ensures that width/height are positive diff --git a/sixtyfps_runtime/rendering_backends/qt/qt_window.rs b/sixtyfps_runtime/rendering_backends/qt/qt_window.rs index f7e6e7c50..690e6b0ad 100644 --- a/sixtyfps_runtime/rendering_backends/qt/qt_window.rs +++ b/sixtyfps_runtime/rendering_backends/qt/qt_window.rs @@ -10,7 +10,7 @@ LICENSE END */ use cpp::*; use items::{ImageFit, TextHorizontalAlignment, TextVerticalAlignment}; -use sixtyfps_corelib::graphics::{Brush, FontRequest, Point, Rect, RenderingCache, Size}; +use sixtyfps_corelib::graphics::{Brush, FontRequest, Image, Point, Rect, RenderingCache, Size}; use sixtyfps_corelib::input::{InternalKeyCode, KeyEvent, KeyEventType, MouseEvent}; use sixtyfps_corelib::item_rendering::{CachedRenderingData, ItemRenderer}; use sixtyfps_corelib::items::{self, FillRule, ItemRef, TextOverflow, TextWrap}; @@ -820,7 +820,7 @@ impl QtItemRenderer<'_> { fn draw_image_impl( &mut self, item_cache: &CachedRenderingData, - source_property: Pin<&Property>, + source_property: Pin<&Property>, dest_rect: qttypes::QRectF, source_rect: Option, target_width: std::pin::Pin<&Property>, @@ -851,7 +851,7 @@ impl QtItemRenderer<'_> { None }; - load_image_from_resource(&source_property.get(), source_size, image_fit).map_or( + load_image_from_resource(&source_property.get().0, source_size, image_fit).map_or( QtRenderingCacheItem::Invalid, |mut pixmap: qttypes::QPixmap| { let colorize = colorize_property.map_or(Brush::default(), |c| c.get()); diff --git a/xtask/src/cbindgen.rs b/xtask/src/cbindgen.rs index 6927ed98a..7d37d30f2 100644 --- a/xtask/src/cbindgen.rs +++ b/xtask/src/cbindgen.rs @@ -110,6 +110,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> { "SharedString", "SharedVector", "ImageReference", + "Image", "Color", "PathData", "PathElement", @@ -179,7 +180,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> { .write_to_file(include_dir.join("sixtyfps_properties_internal.h")); for (rust_types, extra_excluded_types, internal_header) in [ - (vec!["ImageReference"], vec![], "sixtyfps_image_internal.h"), + (vec!["ImageReference", "Image"], vec![], "sixtyfps_image_internal.h"), ( vec!["Color", "sixtyfps_color_brighter", "sixtyfps_color_darker"], vec![], @@ -248,6 +249,7 @@ fn gen_corelib(root_dir: &Path, include_dir: &Path) -> anyhow::Result<()> { .with_src(crate_dir.join("graphics/color.rs")) .with_src(crate_dir.join("graphics/path.rs")) .with_src(crate_dir.join("graphics/brush.rs")) + .with_src(crate_dir.join("graphics/image.rs")) .with_src(crate_dir.join("animations.rs")) // .with_src(crate_dir.join("input.rs")) .with_src(crate_dir.join("item_rendering.rs"))