Move the fonts out of the Backend trait (#1438)

and remove the `'static`
This commit is contained in:
Olivier Goffart 2022-07-26 16:45:54 +02:00 committed by GitHub
parent 793974ce9f
commit 8c70cd7f57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 167 additions and 251 deletions

View file

@ -194,6 +194,36 @@ public:
cbindgen_private::slint_windowrc_set_size(&inner, &size);
}
/// Registers a font by the specified path. The path must refer to an existing
/// TrueType font.
/// \returns an empty optional on success, otherwise an error string
inline std::optional<SharedString> register_font_from_path(const SharedString &path)
{
SharedString maybe_err;
cbindgen_private::slint_register_font_from_path(&inner, &path, &maybe_err);
if (!maybe_err.empty()) {
return maybe_err;
} else {
return {};
}
}
/// Registers a font by the data. The data must be valid TrueType font data.
/// \returns an empty optional on success, otherwise an error string
inline std::optional<SharedString> register_font_from_data(const uint8_t *data, std::size_t len)
{
SharedString maybe_err;
cbindgen_private::slint_register_font_from_data(&inner, { const_cast<uint8_t *>(data), len },
&maybe_err);
if (!maybe_err.empty()) {
return maybe_err;
} else {
return {};
}
}
private:
cbindgen_private::WindowRcOpaque inner;
};
@ -1106,36 +1136,4 @@ auto blocking_invoke_from_event_loop(Functor f) -> void
cv.wait(lock, [&] { return ok; });
}
namespace private_api {
/// Registers a font by the specified path. The path must refer to an existing
/// TrueType font.
/// \returns an empty optional on success, otherwise an error string
inline std::optional<SharedString> register_font_from_path(const SharedString &path)
{
SharedString maybe_err;
cbindgen_private::slint_register_font_from_path(&path, &maybe_err);
if (!maybe_err.empty()) {
return maybe_err;
} else {
return {};
}
}
/// Registers a font by the data. The data must be valid TrueType font data.
/// \returns an empty optional on success, otherwise an error string
inline std::optional<SharedString> register_font_from_data(const uint8_t *data, std::size_t len)
{
SharedString maybe_err;
cbindgen_private::slint_register_font_from_data({ const_cast<uint8_t *>(data), len },
&maybe_err);
if (!maybe_err.empty()) {
return maybe_err;
} else {
return {};
}
}
}
} // namespace slint

View file

@ -6,7 +6,7 @@
use core::ffi::c_void;
use i_slint_backend_selector::backend;
use i_slint_core::api::Window;
use i_slint_core::window::ffi::WindowRcOpaque;
use i_slint_core::window::{ffi::WindowRcOpaque, WindowRc};
#[doc(hidden)]
#[cold]
@ -63,12 +63,14 @@ pub unsafe extern "C" fn slint_quit_event_loop() {
#[no_mangle]
pub unsafe extern "C" fn slint_register_font_from_path(
win: *const WindowRcOpaque,
path: &i_slint_core::SharedString,
error_str: *mut i_slint_core::SharedString,
) {
let window = &*(win as *const WindowRc);
core::ptr::write(
error_str,
match crate::backend().register_font_from_path(std::path::Path::new(path.as_str())) {
match window.renderer().register_font_from_path(std::path::Path::new(path.as_str())) {
Ok(()) => Default::default(),
Err(err) => err.to_string().into(),
},
@ -77,12 +79,14 @@ pub unsafe extern "C" fn slint_register_font_from_path(
#[no_mangle]
pub unsafe extern "C" fn slint_register_font_from_data(
win: *const WindowRcOpaque,
data: i_slint_core::slice::Slice<'static, u8>,
error_str: *mut i_slint_core::SharedString,
) {
let window = &*(win as *const WindowRc);
core::ptr::write(
error_str,
match crate::backend().register_font_from_memory(data.as_slice()) {
match window.renderer().register_font_from_memory(data.as_slice()) {
Ok(()) => Default::default(),
Err(err) => err.to_string().into(),
},

View file

@ -253,26 +253,6 @@ pub use i_slint_core::sharedvector::SharedVector;
pub use i_slint_core::string::SharedString;
pub use i_slint_core::timers::{Timer, TimerMode};
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided slice must be a valid TrueType
/// font.
#[doc(hidden)]
#[cfg(feature = "std")]
pub fn register_font_from_memory(data: &'static [u8]) -> Result<(), Box<dyn std::error::Error>> {
i_slint_backend_selector::backend().register_font_from_memory(data)
}
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided path must refer to a valid TrueType
/// font.
#[doc(hidden)]
#[cfg(feature = "std")]
pub fn register_font_from_path<P: AsRef<std::path::Path>>(
path: P,
) -> Result<(), Box<dyn std::error::Error>> {
i_slint_backend_selector::backend().register_font_from_path(path.as_ref())
}
/// internal re_exports used by the macro generated
#[doc(hidden)]
pub mod re_exports {
@ -440,12 +420,6 @@ pub mod internal {
})
}
/// This function can be used to register a pre-rendered, embedded bitmap font with Slint,
/// for use with the `font-family` property.
pub fn register_bitmap_font(font_data: &'static super::re_exports::BitmapFont) {
i_slint_backend_selector::backend().register_bitmap_font(font_data)
}
pub fn debug(s: SharedString) {
#[cfg(feature = "log")]
log::debug!("{s}");

View file

@ -44,7 +44,7 @@ pub use stylemetrics::native_style_metrics_init;
pub struct Backend;
impl i_slint_core::backend::Backend for Backend {
fn create_window(&'static self) -> i_slint_core::api::Window {
fn create_window(&self) -> i_slint_core::api::Window {
i_slint_core::window::WindowInner::new(|window| {
GLWindow::new(
window,
@ -55,31 +55,17 @@ impl i_slint_core::backend::Backend for Backend {
.into()
}
fn run_event_loop(&'static self, behavior: i_slint_core::backend::EventLoopQuitBehavior) {
fn run_event_loop(&self, behavior: i_slint_core::backend::EventLoopQuitBehavior) {
crate::event_loop::run(behavior);
}
fn quit_event_loop(&'static self) {
fn quit_event_loop(&self) {
crate::event_loop::with_window_target(|event_loop| {
event_loop.event_loop_proxy().send_event(crate::event_loop::CustomEvent::Exit).ok();
})
}
fn register_font_from_memory(
&'static self,
data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
self::renderer::femtovg::FemtoVGRenderer::register_font_from_memory(data)
}
fn register_font_from_path(
&'static self,
path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
self::renderer::femtovg::FemtoVGRenderer::register_font_from_path(path)
}
fn post_event(&'static self, event: Box<dyn FnOnce() + Send>) {
fn post_event(&self, event: Box<dyn FnOnce() + Send>) {
let e = crate::event_loop::CustomEvent::UserEvent(event);
#[cfg(not(target_arch = "wasm32"))]
crate::event_loop::GLOBAL_PROXY.get_or_init(Default::default).lock().unwrap().send_event(e);

View file

@ -312,16 +312,16 @@ impl Renderer for FemtoVGRenderer {
Rect::new(result / scale_factor, Size::new(1.0, font_size))
}
}
impl FemtoVGRenderer {
pub fn register_font_from_memory(
fn register_font_from_memory(
&self,
data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
fonts::register_font_from_memory(data)
}
pub fn register_font_from_path(
fn register_font_from_path(
&self,
path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
fonts::register_font_from_path(path)

View file

@ -122,9 +122,9 @@ mod the_backend {
use i_slint_core::window::WindowInner;
thread_local! { static WINDOWS: RefCell<Option<Rc<McuWindow>>> = RefCell::new(None) }
thread_local! { static EVENT_QUEUE: RefCell<VecDeque<McuEvent>> = Default::default() }
pub struct McuWindow {
backend: &'static MCUBackend,
self_weak: Weak<WindowInner>,
renderer: crate::renderer::SoftwareRenderer,
}
@ -142,7 +142,7 @@ mod the_backend {
WINDOWS.with(|x| *x.borrow_mut() = None)
}
fn request_redraw(&self) {
self.backend.with_inner(|inner| inner.post_event(McuEvent::Repaint))
EVENT_QUEUE.with(|q| q.borrow_mut().push_back(McuEvent::Repaint))
}
fn renderer(&self) -> &dyn i_slint_core::renderer::Renderer {
@ -170,17 +170,9 @@ mod the_backend {
#[derive(Default)]
struct MCUBackendInner {
event_queue: VecDeque<McuEvent>,
clipboard: String,
}
impl MCUBackendInner {
fn post_event(&mut self, event: McuEvent) {
self.event_queue.push_back(event);
// TODO! wake
}
}
#[derive(Default)]
pub struct MCUBackend {
#[cfg(all(not(feature = "std"), feature = "unsafe_single_core"))]
@ -297,21 +289,17 @@ mod the_backend {
}
impl i_slint_core::backend::Backend for MCUBackend {
fn create_window(&'static self) -> i_slint_core::api::Window {
fn create_window(&self) -> i_slint_core::api::Window {
i_slint_core::window::WindowInner::new(|window| {
Rc::new(McuWindow {
backend: self,
self_weak: window.clone(),
renderer: Default::default(),
})
Rc::new(McuWindow { self_weak: window.clone(), renderer: Default::default() })
})
.into()
}
fn run_event_loop(&'static self, behavior: i_slint_core::backend::EventLoopQuitBehavior) {
fn run_event_loop(&self, behavior: i_slint_core::backend::EventLoopQuitBehavior) {
loop {
i_slint_core::timers::update_timers();
match self.with_inner(|inner| inner.event_queue.pop_front()) {
match EVENT_QUEUE.with(|q| q.borrow_mut().pop_front()) {
Some(McuEvent::Quit) => break,
Some(McuEvent::Custom(e)) => e(),
Some(McuEvent::Repaint) => {
@ -359,22 +347,15 @@ mod the_backend {
}
}
fn quit_event_loop(&'static self) {
self.with_inner(|inner| inner.post_event(McuEvent::Quit))
fn quit_event_loop(&self) {
EVENT_QUEUE.with(|q| q.borrow_mut().push_back(McuEvent::Quit));
}
fn register_bitmap_font(
&'static self,
font_data: &'static i_slint_core::graphics::BitmapFont,
) {
crate::renderer::fonts::register_bitmap_font(font_data);
fn post_event(&self, event: Box<dyn FnOnce() + Send>) {
EVENT_QUEUE.with(|q| q.borrow_mut().push_back(McuEvent::Custom(event)));
}
fn post_event(&'static self, event: Box<dyn FnOnce() + Send>) {
self.with_inner(|inner| inner.post_event(McuEvent::Custom(event)));
}
fn duration_since_start(&'static self) -> core::time::Duration {
fn duration_since_start(&self) -> core::time::Duration {
DEVICES.with(|devices| devices.borrow_mut().as_mut().unwrap().time())
}

View file

@ -330,41 +330,22 @@ impl WinitWindow for SimulatorWindow {
pub struct SimulatorBackend;
impl i_slint_core::backend::Backend for SimulatorBackend {
fn create_window(&'static self) -> i_slint_core::api::Window {
fn create_window(&self) -> i_slint_core::api::Window {
i_slint_core::window::WindowInner::new(|window| SimulatorWindow::new(window)).into()
}
fn run_event_loop(&'static self, behavior: i_slint_core::backend::EventLoopQuitBehavior) {
fn run_event_loop(&self, behavior: i_slint_core::backend::EventLoopQuitBehavior) {
event_loop::run(behavior);
std::process::exit(0);
}
fn quit_event_loop(&'static self) {
fn quit_event_loop(&self) {
self::event_loop::with_window_target(|event_loop| {
event_loop.event_loop_proxy().send_event(self::event_loop::CustomEvent::Exit).ok();
})
}
fn register_font_from_memory(
&'static self,
_data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
//TODO
Err("Not implemented".into())
}
fn register_font_from_path(
&'static self,
_path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!()
}
fn register_bitmap_font(&'static self, font_data: &'static i_slint_core::graphics::BitmapFont) {
crate::renderer::fonts::register_bitmap_font(font_data);
}
fn post_event(&'static self, event: Box<dyn FnOnce() + Send>) {
fn post_event(&self, event: Box<dyn FnOnce() + Send>) {
self::event_loop::GLOBAL_PROXY
.get_or_init(Default::default)
.lock()

View file

@ -135,7 +135,7 @@ pub fn native_style_metrics_deinit(_: core::pin::Pin<&mut native_widgets::Native
pub struct Backend;
impl i_slint_core::backend::Backend for Backend {
fn create_window(&'static self) -> i_slint_core::api::Window {
fn create_window(&self) -> i_slint_core::api::Window {
#[cfg(no_qt)]
panic!("The Qt backend needs Qt");
#[cfg(not(no_qt))]
@ -144,7 +144,7 @@ impl i_slint_core::backend::Backend for Backend {
}
}
fn run_event_loop(&'static self, _behavior: i_slint_core::backend::EventLoopQuitBehavior) {
fn run_event_loop(&self, _behavior: i_slint_core::backend::EventLoopQuitBehavior) {
#[cfg(not(no_qt))]
{
let quit_on_last_window_closed = match _behavior {
@ -162,7 +162,7 @@ impl i_slint_core::backend::Backend for Backend {
};
}
fn quit_event_loop(&'static self) {
fn quit_event_loop(&self) {
#[cfg(not(no_qt))]
{
use cpp::cpp;
@ -176,47 +176,7 @@ impl i_slint_core::backend::Backend for Backend {
};
}
fn register_font_from_memory(
&'static self,
_data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
#[cfg(not(no_qt))]
{
use cpp::cpp;
let data = qttypes::QByteArray::from(_data);
cpp! {unsafe [data as "QByteArray"] {
ensure_initialized(true);
QFontDatabase::addApplicationFontFromData(data);
} }
};
Ok(())
}
fn register_font_from_path(
&'static self,
_path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
#[cfg(not(no_qt))]
{
use cpp::cpp;
let encoded_path: qttypes::QByteArray = _path.to_string_lossy().as_bytes().into();
cpp! {unsafe [encoded_path as "QByteArray"] {
ensure_initialized(true);
QString requested_path = QFileInfo(QFile::decodeName(encoded_path)).canonicalFilePath();
static QSet<QString> loaded_app_fonts;
// QFontDatabase::addApplicationFont unconditionally reads the provided file from disk,
// while we want to do this only once to avoid things like the live-review going crazy.
if (!loaded_app_fonts.contains(requested_path)) {
loaded_app_fonts.insert(requested_path);
QFontDatabase::addApplicationFont(requested_path);
}
} }
};
Ok(())
}
fn post_event(&'static self, _event: Box<dyn FnOnce() + Send>) {
fn post_event(&self, _event: Box<dyn FnOnce() + Send>) {
#[cfg(not(no_qt))]
{
use cpp::cpp;
@ -256,7 +216,7 @@ impl i_slint_core::backend::Backend for Backend {
};
}
fn set_clipboard_text(&'static self, _text: &str) {
fn set_clipboard_text(&self, _text: &str) {
#[cfg(not(no_qt))]
{
use cpp::cpp;
@ -268,7 +228,7 @@ impl i_slint_core::backend::Backend for Backend {
}
}
fn clipboard_text(&'static self) -> Option<String> {
fn clipboard_text(&self) -> Option<String> {
#[cfg(not(no_qt))]
{
use cpp::cpp;

View file

@ -1709,6 +1709,38 @@ impl Renderer for QtWindow {
Rect::new(Point::new(r.x as _, r.y as _), Size::new(1.0, font_size as f32))
}
fn register_font_from_memory(
&self,
data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
let data = qttypes::QByteArray::from(data);
cpp! {unsafe [data as "QByteArray"] {
ensure_initialized(true);
QFontDatabase::addApplicationFontFromData(data);
} }
Ok(())
}
fn register_font_from_path(
&self,
path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
let encoded_path: qttypes::QByteArray = path.to_string_lossy().as_bytes().into();
cpp! {unsafe [encoded_path as "QByteArray"] {
ensure_initialized(true);
QString requested_path = QFileInfo(QFile::decodeName(encoded_path)).canonicalFilePath();
static QSet<QString> loaded_app_fonts;
// QFontDatabase::addApplicationFont unconditionally reads the provided file from disk,
// while we want to do this only once to avoid things like the live-review going crazy.
if (!loaded_app_fonts.contains(requested_path)) {
loaded_app_fonts.insert(requested_path);
QFontDatabase::addApplicationFont(requested_path);
}
} }
Ok(())
}
}
fn accessible_item(item: Option<ItemRc>) -> Option<ItemRc> {

View file

@ -20,44 +20,30 @@ pub struct TestingBackend {
}
impl i_slint_core::backend::Backend for TestingBackend {
fn create_window(&'static self) -> Window {
fn create_window(&self) -> Window {
WindowInner::new(|_| Rc::new(TestingWindow::default())).into()
}
fn run_event_loop(&'static self, _behavior: i_slint_core::backend::EventLoopQuitBehavior) {
fn run_event_loop(&self, _behavior: i_slint_core::backend::EventLoopQuitBehavior) {
unimplemented!("running an event loop with the testing backend");
}
fn quit_event_loop(&'static self) {}
fn quit_event_loop(&self) {}
fn register_font_from_memory(
&'static self,
_data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn register_font_from_path(
&'static self,
_path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn post_event(&'static self, _event: Box<dyn FnOnce() + Send>) {
fn post_event(&self, _event: Box<dyn FnOnce() + Send>) {
// The event will never be invoked
}
fn duration_since_start(&'static self) -> core::time::Duration {
fn duration_since_start(&self) -> core::time::Duration {
// The slint::testing::mock_elapsed_time updates the animation tick directly
core::time::Duration::from_millis(i_slint_core::animations::current_tick().0)
}
fn set_clipboard_text(&'static self, text: &str) {
fn set_clipboard_text(&self, text: &str) {
*self.clipboard.lock().unwrap() = Some(text.into());
}
fn clipboard_text(&'static self) -> Option<String> {
fn clipboard_text(&self) -> Option<String> {
self.clipboard.lock().unwrap().clone()
}
}
@ -149,6 +135,20 @@ impl Renderer for TestingWindow {
) -> Rect {
Default::default()
}
fn register_font_from_memory(
&self,
_data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
fn register_font_from_path(
&self,
_path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
}
/// Initialize the testing backend.

View file

@ -2453,7 +2453,8 @@ fn compile_builtin_function_call(
}
BuiltinFunction::RegisterCustomFontByPath => {
if let [llr::Expression::StringLiteral(path)] = arguments {
format!("slint::private_api::register_font_from_path(\"{}\");", escape_string(path))
let window = access_window_field(ctx);
format!("{window}.register_font_from_path(\"{}\");", escape_string(path))
} else {
panic!(
"internal error: argument to RegisterCustomFontByPath must be a string literal"
@ -2462,12 +2463,10 @@ fn compile_builtin_function_call(
}
BuiltinFunction::RegisterCustomFontByMemory => {
if let [llr::Expression::NumberLiteral(resource_id)] = &arguments {
let window = access_window_field(ctx);
let resource_id: usize = *resource_id as _;
let symbol = format!("slint_embedded_resource_{}", resource_id);
format!(
"slint::private_api::register_font_from_data({}, std::size({}));",
symbol, symbol
)
format!("{window}.register_font_from_data({symbol}, std::size({symbol}));")
} else {
panic!("internal error: invalid args to RegisterCustomFontByMemory {:?}", arguments)
}

View file

@ -2039,7 +2039,8 @@ fn compile_builtin_function_call(
}
BuiltinFunction::RegisterCustomFontByPath => {
if let [Expression::StringLiteral(path)] = arguments {
quote!(slint::register_font_from_path(&std::path::PathBuf::from(#path));)
let window_tokens = access_window_field(ctx);
quote!(#window_tokens.renderer().register_font_from_path(&std::path::PathBuf::from(#path));)
} else {
panic!("internal error: invalid args to RegisterCustomFontByPath {:?}", arguments)
}
@ -2048,7 +2049,8 @@ fn compile_builtin_function_call(
if let [Expression::NumberLiteral(resource_id)] = &arguments {
let resource_id: usize = *resource_id as _;
let symbol = format_ident!("SLINT_EMBEDDED_RESOURCE_{}", resource_id);
quote!(slint::register_font_from_memory(#symbol.into());)
let window_tokens = access_window_field(ctx);
quote!(#window_tokens.renderer().register_font_from_memory(#symbol.into());)
} else {
panic!("internal error: invalid args to RegisterCustomFontByMemory {:?}", arguments)
}
@ -2057,7 +2059,8 @@ fn compile_builtin_function_call(
if let [Expression::NumberLiteral(resource_id)] = &arguments {
let resource_id: usize = *resource_id as _;
let symbol = format_ident!("SLINT_EMBEDDED_RESOURCE_{}", resource_id);
quote!(slint::internal::register_bitmap_font(&#symbol);)
let window_tokens = access_window_field(ctx);
quote!(#window_tokens.renderer().register_bitmap_font(&#symbol);)
} else {
panic!("internal error: invalid args to RegisterBitmapFont must be a number")
}

View file

@ -26,42 +26,15 @@ pub enum EventLoopQuitBehavior {
/// Interface implemented by back-ends
pub trait Backend: Send + Sync {
/// Instantiate a window for a component.
/// FIXME: should return a Box<dyn PlatformWindow>
fn create_window(&'static self) -> crate::api::Window;
fn create_window(&self) -> crate::api::Window;
/// Spins an event loop and renders the visible windows.
fn run_event_loop(&'static self, _behavior: EventLoopQuitBehavior) {
fn run_event_loop(&self, _behavior: EventLoopQuitBehavior) {
unimplemented!()
}
/// Exits the event loop.
fn quit_event_loop(&'static self) {
unimplemented!()
}
#[cfg(feature = "std")] // FIXME: just because of the Error
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided slice must be a valid TrueType
/// font.
fn register_font_from_memory(
&'static self,
_data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!()
}
#[cfg(feature = "std")]
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided path must refer to a valid TrueType
/// font.
fn register_font_from_path(
&'static self,
_path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!()
}
fn register_bitmap_font(&'static self, _font_data: &'static crate::graphics::BitmapFont) {
fn quit_event_loop(&self) {
unimplemented!()
}

View file

@ -47,4 +47,30 @@ pub trait Renderer {
///
/// Example: when a PopupWindow disapear, the region under the popup needs to be redrawn
fn mark_dirty_region(&self, _region: crate::item_rendering::DirtyRegion) {}
#[cfg(feature = "std")] // FIXME: just because of the Error
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided slice must be a valid TrueType
/// font.
fn register_font_from_memory(
&self,
_data: &'static [u8],
) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!()
}
#[cfg(feature = "std")]
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided path must refer to a valid TrueType
/// font.
fn register_font_from_path(
&self,
_path: &std::path::Path,
) -> Result<(), Box<dyn std::error::Error>> {
unimplemented!()
}
fn register_bitmap_font(&self, _font_data: &'static crate::graphics::BitmapFont) {
unimplemented!()
}
}

View file

@ -192,6 +192,10 @@ impl Renderer for SoftwareRenderer {
fn mark_dirty_region(&self, region: crate::item_rendering::DirtyRegion) {
self.force_dirty.set(self.force_dirty.get().union(&region))
}
fn register_bitmap_font(&self, font_data: &'static crate::graphics::BitmapFont) {
fonts::register_bitmap_font(font_data);
}
}
fn render_window_frame_by_line(

View file

@ -461,8 +461,12 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon
if arguments.len() != 1 {
panic!("internal error: incorrect argument count to RegisterCustomFontByPath")
}
let component = match local_context.component_instance {
ComponentInstance::InstanceRef(c) => c,
ComponentInstance::GlobalComponent(_) => panic!("Cannot access the implicit item size from a global component")
};
if let Value::String(s) = eval_expression(&arguments[0], local_context) {
if let Some(err) = crate::register_font_from_path(&std::path::PathBuf::from(s.as_str())).err() {
if let Some(err) = window_ref(component).unwrap().renderer().register_font_from_path(&std::path::PathBuf::from(s.as_str())).err() {
corelib::debug_log!("Error loading custom font {}: {}", s.as_str(), err);
}
Value::Void

View file

@ -85,15 +85,6 @@ mod value_model;
#[doc(inline)]
pub use api::*;
/// This function can be used to register a custom TrueType font with Slint,
/// for use with the `font-family` property. The provided path must refer to a valid TrueType
/// font.
pub(crate) fn register_font_from_path<P: AsRef<std::path::Path>>(
path: P,
) -> Result<(), Box<dyn std::error::Error>> {
i_slint_backend_selector::backend().register_font_from_path(path.as_ref())
}
/// (Re-export from corelib.)
#[doc(inline)]
pub use i_slint_core::{Brush, Color, SharedString, SharedVector};