C++: Generate image texture data for software renderer

This commit is contained in:
Olivier Goffart 2022-12-08 16:38:37 +01:00
parent b2ebac63c2
commit ccf3e8e9e9
6 changed files with 117 additions and 33 deletions

View file

@ -203,6 +203,7 @@ fn gen_corelib(
"slint_image_path",
"slint_image_load_from_path",
"slint_image_load_from_embedded_data",
"slint_image_from_embedded_textures",
"Coord",
"LogicalRect",
"LogicalPoint",
@ -272,6 +273,7 @@ fn gen_corelib(
"slint_image_path",
"slint_image_load_from_path",
"slint_image_load_from_embedded_data",
"slint_image_from_embedded_textures",
"SharedPixelBuffer",
"SharedImageBuffer",
"StaticTextures",
@ -333,6 +335,7 @@ fn gen_corelib(
"slint_image_path",
"slint_image_load_from_path",
"slint_image_load_from_embedded_data",
"slint_image_from_embedded_textures",
]
.iter()
.filter(|exclusion| !rust_types.iter().any(|inclusion| inclusion == *exclusion))

View file

@ -74,6 +74,13 @@ inline Image load_image_from_embedded_data(std::span<const uint8_t> data,
&img);
return Image(img);
}
inline Image image_from_embedded_textures(const cbindgen_private::types::StaticTextures *textures)
{
cbindgen_private::types::Image img(cbindgen_private::types::Image::ImageInner_None());
cbindgen_private::types::slint_image_from_embedded_textures(textures, &img);
return Image(img);
}
}
}

View file

@ -35,6 +35,7 @@ software-renderer = ["image", "tiny-skia", "resvg", "usvg", "fontdb", "fontdue",
i-slint-common = { version = "=0.3.3", path = "../common" }
num_enum = "0.5.1"
strum = { version = "0.24.0", default-features = false, features = ["derive"] }
rowan = "0.15.5"
smol_str = "0.1.17"
derive_more = "0.99.5"

View file

@ -10,7 +10,7 @@ pub struct Size {
pub height: u32,
}
#[derive(Clone, Copy, Debug)]
#[derive(Clone, Copy, Debug, strum::Display)]
pub enum PixelFormat {
// 24 bit RGB
Rgb,

View file

@ -479,12 +479,12 @@ pub fn generate(doc: &Document) -> impl std::fmt::Display {
file.includes.push("<cmath>".into()); // TODO: ideally only include this if needed (by floor/ceil/round)
file.includes.push("<slint.h>".into());
file.declarations.extend(doc.root_component.embedded_file_resources.borrow().iter().map(
|(path, er)| {
for (path, er) in doc.root_component.embedded_file_resources.borrow().iter() {
match &er.kind {
crate::embedded_resources::EmbeddedResourcesKind::RawData => {
let file = crate::fileaccess::load_file(std::path::Path::new(path)).unwrap(); // embedding pass ensured that the file exists
let data = file.read();
let resource_file =
crate::fileaccess::load_file(std::path::Path::new(path)).unwrap(); // embedding pass ensured that the file exists
let data = resource_file.read();
let mut init = "{ ".to_string();
@ -500,20 +500,82 @@ pub fn generate(doc: &Document) -> impl std::fmt::Display {
init.push('}');
Declaration::Var(Var {
file.declarations.push(Declaration::Var(Var {
ty: "inline uint8_t".into(),
name: format!("slint_embedded_resource_{}", er.id),
array_size: Some(data.len()),
init: Some(init),
})
}));
}
#[cfg(feature = "software-renderer")]
crate::embedded_resources::EmbeddedResourcesKind::TextureData(_) => todo!(),
#[cfg(feature = "software-renderer")]
crate::embedded_resources::EmbeddedResourcesKind::BitmapFontData(_) => todo!(),
}
crate::embedded_resources::EmbeddedResourcesKind::TextureData(
crate::embedded_resources::Texture {
data,
format,
rect,
total_size: crate::embedded_resources::Size { width, height },
original_size:
crate::embedded_resources::Size {
width: unscaled_width,
height: unscaled_height,
},
));
},
) => {
let (r_x, r_y, r_w, r_h) = (rect.x(), rect.y(), rect.width(), rect.height());
let color =
if let crate::embedded_resources::PixelFormat::AlphaMap([r, g, b]) = format {
format!("slint::Color::from_rgb_uint8({r}, {g}, {b})")
} else {
"slint::Color{}".to_string()
};
let count = data.len();
let data = data.iter().map(ToString::to_string).join(", ");
let data_name = format!("slint_embedded_resource_{}_data", er.id);
file.declarations.push(Declaration::Var(Var {
ty: "inline uint8_t".into(),
name: data_name.clone(),
array_size: Some(count),
init: Some(format!("{{ {data} }}")),
}));
let texture_name = format!("slint_embedded_resource_{}_texture", er.id);
file.declarations.push(Declaration::Var(Var {
ty: "inline slint::cbindgen_private::types::StaticTexture".into(),
name: texture_name.clone(),
array_size: None,
init: Some(format!(
"{{
.rect = {{ {r_x}, {r_y}, {r_w}, {r_h} }},
.format = slint::cbindgen_private::types::PixelFormat::{format},
.color = {color},
.index = 0,
}}"
)),
}));
let init = format!("slint::cbindgen_private::types::StaticTextures {{
.size = {{ {width}, {height} }},
.original_size = {{ {unscaled_width}, {unscaled_height} }},
.data = slint::cbindgen_private::Slice<uint8_t>{{ {data_name} , {count} }},
.textures = slint::cbindgen_private::Slice<slint::cbindgen_private::types::StaticTexture>{{ &{texture_name}, 1 }}
}}");
file.declarations.push(Declaration::Var(Var {
ty: "inline slint::cbindgen_private::types::StaticTextures".into(),
name: format!("slint_embedded_resource_{}", er.id),
array_size: None,
init: Some(init),
}))
}
#[cfg(feature = "software-renderer")]
crate::embedded_resources::EmbeddedResourcesKind::BitmapFontData(_) => {
// FIXME! TODO
file.declarations.push(Declaration::Var(Var {
ty: "inline int".into(),
name: format!("slint_embedded_resource_{}", er.id),
array_size: None,
init: Some("0".into()),
}))
}
}
}
for ty in doc.root_component.used_types.borrow().structs.iter() {
if let Type::Struct { fields, name: Some(name), node: Some(_) } = ty {
@ -2319,7 +2381,9 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
let symbol = format!("slint_embedded_resource_{}", resource_id);
format!(r#"slint::private_api::load_image_from_embedded_data({symbol}, "{}")"#, escape_string(extension))
}
crate::expression_tree::ImageReference::EmbeddedTexture{..} => todo!(),
crate::expression_tree::ImageReference::EmbeddedTexture{resource_id} => {
format!("slint::private_api::image_from_embedded_textures(&slint_embedded_resource_{resource_id})")
},
}
}
Expression::Condition { condition, true_expr, false_expr } => {
@ -2594,7 +2658,8 @@ fn compile_builtin_function_call(
}
}
BuiltinFunction::RegisterBitmapFont => {
todo!()
// TODO
"/*TODO: REGISTER FONT*/".into()
}
BuiltinFunction::ImplicitLayoutInfo(orient) => {
if let [llr::Expression::PropertyReference(pr)] = arguments {

View file

@ -733,4 +733,12 @@ pub(crate) mod ffi {
_ => None,
}
}
#[no_mangle]
pub unsafe extern "C" fn slint_image_from_embedded_textures(
textures: &'static StaticTextures,
image: *mut Image,
) {
core::ptr::write(image, Image::from(ImageInner::StaticTextures(textures)));
}
}