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

C++: add a "std" feature to the slint-cpp crate #3050

Merged
merged 3 commits into from Jul 5, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 2 additions & 4 deletions api/cpp/CMakeLists.txt
Expand Up @@ -49,10 +49,7 @@ set_property(
)

if(SLINT_FEATURE_COMPILER)
set_property(
TARGET slint-compiler
PROPERTY CORROSION_USE_HOST_BUILD 1
)
corrosion_set_hostbuild(slint-compiler)
endif()

add_library(Slint INTERFACE)
Expand Down Expand Up @@ -137,6 +134,7 @@ set_property(
TARGET slint-cpp
PROPERTY CORROSION_FEATURES
${features}
std
)
set_property(
TARGET slint-cpp
Expand Down
12 changes: 7 additions & 5 deletions api/cpp/Cargo.toml
Expand Up @@ -38,19 +38,21 @@ renderer-winit-software = ["i-slint-backend-selector/renderer-winit-software"]
gettext = ["i-slint-core/gettext-rs"]
accessibility = ["i-slint-backend-selector/accessibility"]

experimental = ["i-slint-renderer-skia", "raw-window-handle"]
experimental = ["i-slint-renderer-skia", "raw-window-handle", "std"]

default = ["backend-winit", "renderer-winit-femtovg", "backend-qt", "experimental"]
std = ["image", "i-slint-core/default", "i-slint-backend-selector"]

default = ["std", "backend-winit", "renderer-winit-femtovg", "backend-qt", "experimental"]

[dependencies]
i-slint-backend-selector = { version = "=1.1.1", path="../../internal/backends/selector" }
i-slint-backend-selector = { version = "=1.1.1", path="../../internal/backends/selector", optional = true }
i-slint-backend-testing = { version = "=1.1.1", path="../../internal/backends/testing", optional = true }
i-slint-renderer-skia = { version = "=1.1.1", path="../../internal/renderers/skia", optional = true, features = ["x11", "wayland"] }
i-slint-core = { version = "=1.1.1", path="../../internal/core", features = ["ffi"] }
i-slint-core = { version = "=1.1.1", path="../../internal/core", default-features = false, features = ["ffi"] }
slint-interpreter = { version = "=1.1.1", path="../../internal/interpreter", default-features = false, features = ["ffi", "compat-1-0"], optional = true }
raw-window-handle = { version = "0.5", optional = true }
# Enable image-rs' default features to make all image formats to C++ users
image = { version = "0.24.0" }
image = { version = "0.24.0", optional = true }

[build-dependencies]
anyhow = "1.0"
Expand Down
4 changes: 2 additions & 2 deletions api/cpp/include/slint_image.h
Expand Up @@ -140,7 +140,7 @@ struct Image
/// [`slint::Image`] objects created from borrowed OpenGL textures cannot be shared between
/// different windows.
[[nodiscard]] static Image create_from_borrowed_gl_2d_rgba_texture(uint32_t texture_id,
Size<unsigned int> size)
Size<uint32_t> size)
{
return Image(Data::ImageInner_BorrowedOpenGLTexture(
cbindgen_private::types::BorrowedOpenGLTexture { texture_id, size })
Expand Down Expand Up @@ -173,7 +173,7 @@ struct Image
}

/// Returns the size of the Image in pixels.
Size<unsigned int> size() const { return cbindgen_private::types::slint_image_size(&data); }
Size<uint32_t> size() const { return cbindgen_private::types::slint_image_size(&data); }

/// Returns the path of the image on disk, if it was constructed via Image::load_from_path().
std::optional<slint::SharedString> path() const
Expand Down
25 changes: 21 additions & 4 deletions api/cpp/lib.rs
Expand Up @@ -3,13 +3,28 @@

/*! This crate just expose the function used by the C++ integration */

#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;

use alloc::rc::Rc;
use core::ffi::c_void;
use i_slint_core::window::{ffi::WindowAdapterRcOpaque, WindowAdapter};
use std::rc::Rc;

#[cfg(feature = "experimental")]
pub mod platform;

#[cfg(feature = "i-slint-backend-selector")]
use i_slint_backend_selector::with_platform;

#[cfg(not(feature = "i-slint-backend-selector"))]
pub fn with_platform<R>(
f: impl FnOnce(
&dyn i_slint_core::platform::Platform,
) -> Result<R, i_slint_core::platform::PlatformError>,
) -> Result<R, i_slint_core::platform::PlatformError> {
i_slint_core::with_platform(|| Err(i_slint_core::platform::PlatformError::NoPlatform), f)
}

/// One need to make sure something from the crate is exported,
/// otherwise its symbols are not going to be in the final binary
#[cfg(feature = "slint-interpreter")]
Expand All @@ -21,13 +36,13 @@ pub unsafe extern "C" fn slint_windowrc_init(out: *mut WindowAdapterRcOpaque) {
core::mem::size_of::<Rc<dyn WindowAdapter>>(),
core::mem::size_of::<WindowAdapterRcOpaque>()
);
let win = i_slint_backend_selector::with_platform(|b| b.create_window_adapter()).unwrap();
let win = with_platform(|b| b.create_window_adapter()).unwrap();
core::ptr::write(out as *mut Rc<dyn WindowAdapter>, win);
}

#[no_mangle]
pub unsafe extern "C" fn slint_ensure_backend() {
i_slint_backend_selector::with_platform(|_b| {
with_platform(|_b| {
// Nothing to do, just make sure a backend was created
Ok(())
})
Expand All @@ -36,7 +51,7 @@ pub unsafe extern "C" fn slint_ensure_backend() {

#[no_mangle]
pub unsafe extern "C" fn slint_run_event_loop() {
i_slint_backend_selector::with_platform(|b| b.run_event_loop()).unwrap();
with_platform(|b| b.run_event_loop()).unwrap();
}

/// Will execute the given functor in the main thread
Expand Down Expand Up @@ -72,6 +87,7 @@ pub unsafe extern "C" fn slint_quit_event_loop() {
i_slint_core::api::quit_event_loop().unwrap();
}

#[cfg(feature = "std")]
#[no_mangle]
pub unsafe extern "C" fn slint_register_font_from_path(
win: *const WindowAdapterRcOpaque,
Expand All @@ -89,6 +105,7 @@ pub unsafe extern "C" fn slint_register_font_from_path(
)
}

#[cfg(feature = "std")]
#[no_mangle]
pub unsafe extern "C" fn slint_register_font_from_data(
win: *const WindowAdapterRcOpaque,
Expand Down
3 changes: 2 additions & 1 deletion api/cpp/platform.rs
@@ -1,6 +1,8 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.0 OR LicenseRef-Slint-commercial

use alloc::boxed::Box;
use alloc::rc::Rc;
use core::ffi::c_void;
use i_slint_core::api::{PhysicalSize, Window};
use i_slint_core::graphics::{IntSize, Rgb8Pixel};
Expand All @@ -10,7 +12,6 @@ use i_slint_core::software_renderer::{RepaintBufferType, SoftwareRenderer};
use i_slint_core::window::ffi::WindowAdapterRcOpaque;
use i_slint_core::window::{WindowAdapter, WindowAdapterInternal};
use raw_window_handle::{RawDisplayHandle, RawWindowHandle};
use std::rc::Rc;

type WindowAdapterUserData = *mut c_void;

Expand Down
1 change: 1 addition & 0 deletions internal/core/graphics.rs
Expand Up @@ -194,5 +194,6 @@ pub(crate) mod ffi {
y: f32,
}

#[cfg(feature = "std")]
pub use super::path::ffi::*;
}
6 changes: 4 additions & 2 deletions internal/core/graphics/image.rs
Expand Up @@ -775,21 +775,23 @@ pub(crate) mod ffi {
a: u8,
}

#[cfg(feature = "image-decoders")]
#[no_mangle]
pub unsafe extern "C" fn slint_image_load_from_path(path: &SharedString, image: *mut Image) {
std::ptr::write(
core::ptr::write(
image,
Image::load_from_path(std::path::Path::new(path.as_str())).unwrap_or(Image::default()),
)
}

#[cfg(feature = "std")]
#[no_mangle]
pub unsafe extern "C" fn slint_image_load_from_embedded_data(
data: Slice<'static, u8>,
format: Slice<'static, u8>,
image: *mut Image,
) {
std::ptr::write(image, super::load_image_from_embedded_data(data, format));
core::ptr::write(image, super::load_image_from_embedded_data(data, format));
}

#[no_mangle]
Expand Down
2 changes: 1 addition & 1 deletion tests/driver/cpp/Cargo.toml
Expand Up @@ -14,7 +14,7 @@ path = "main.rs"
name = "test-driver-cpp"

[dependencies]
slint-cpp = { path = "../../../api/cpp", default-features = false, features = ["testing"] }
slint-cpp = { path = "../../../api/cpp", default-features = false, features = ["testing", "std"] }

[dev-dependencies]
i-slint-compiler = { path = "../../../internal/compiler", features = ["cpp", "display-diagnostics"] }
Expand Down