-
Notifications
You must be signed in to change notification settings - Fork 756
Gallery Example: Add i18n and dynamic font loading for WASM #9762
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -233,6 +233,14 @@ pub use i_slint_core::{ | |
string::{SharedString, ToSharedString}, | ||
}; | ||
|
||
/// Register a custom font from byte data at runtime. | ||
/// | ||
/// Returns the number of font families that were registered from the provided data. | ||
#[cfg(feature = "shared-fontique")] | ||
pub fn register_font_from_memory(font_data: Vec<u8>) -> usize { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm just wondering what's the most efficient and future proof API. I'm thinking we could have something like That way we could also pass a I see that you are returning the count, any reason to do that? We can also bike shed the name of this function. |
||
i_slint_core::register_font_from_memory(font_data) | ||
} | ||
|
||
pub mod private_unstable_api; | ||
|
||
/// Enters the main event loop. This is necessary in order to receive | ||
|
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -2,5 +2,10 @@ | |||
// SPDX-License-Identifier: MIT | ||||
|
||||
fn main() { | ||||
slint_build::compile("gallery.slint").unwrap(); | ||||
slint_build::compile_with_config( | ||||
"gallery.slint", | ||||
slint_build::CompilerConfiguration::new() | ||||
.with_bundled_translations(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/")), | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the printerdemo only does it for wasm and android. slint/demos/printerdemo/rust/build.rs Line 7 in 55a45a6
I think we should do the same. |
||||
) | ||||
.unwrap(); | ||||
} |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
|
@@ -8,21 +8,39 @@ use wasm_bindgen::prelude::*; | |||
|
||||
slint::include_modules!(); | ||||
|
||||
#[cfg(target_arch = "wasm32")] | ||||
#[wasm_bindgen] | ||||
pub fn load_font_from_bytes(font_data: &[u8]) -> Result<(), JsValue> { | ||||
slint::register_font_from_memory(font_data.to_vec()); | ||||
Ok(()) | ||||
} | ||||
|
||||
use std::rc::Rc; | ||||
|
||||
use slint::{Model, ModelExt, ModelRc, SharedString, StandardListViewItem, VecModel}; | ||||
|
||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] | ||||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] | ||||
pub fn main() { | ||||
// This provides better error messages in debug mode. | ||||
// It's disabled in release mode so it doesn't bloat up the file size. | ||||
#[cfg(all(debug_assertions, target_arch = "wasm32"))] | ||||
console_error_panic_hook::set_once(); | ||||
|
||||
// For native builds, initialize gettext translations | ||||
#[cfg(not(target_arch = "wasm32"))] | ||||
slint::init_translations!(concat!(env!("CARGO_MANIFEST_DIR"), "/lang/")); | ||||
|
||||
let app = App::new().unwrap(); | ||||
|
||||
// For WASM builds, select translation after App::new() | ||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Probably something we should do in i_slint_core instead. slint/internal/core/translations.rs Line 375 in 783f740
Actually, we're already using the |
||||
#[cfg(target_arch = "wasm32")] | ||||
if let Some(window) = web_sys::window() { | ||||
if let Some(lang) = window.navigator().language() { | ||||
let lang_code = lang.split('-').next().unwrap_or("en"); | ||||
let _ = slint::select_bundled_translation(lang_code); | ||||
} | ||||
} | ||||
|
||||
let row_data: Rc<VecModel<slint::ModelRc<StandardListViewItem>>> = Rc::new(VecModel::default()); | ||||
|
||||
for r in 1..101 { | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -131,6 +131,26 @@ impl std::ops::DerefMut for Collection { | |
} | ||
} | ||
|
||
/// Register a font from byte data dynamically. | ||
pub fn register_font_from_memory(font_data: Vec<u8>) -> usize { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm just wondering what's the most efficient and future proof API. I'm thinking we could have something like That way we could also pass a |
||
let blob = fontique::Blob::new(Arc::new(font_data)); | ||
|
||
let mut collection = get_collection(); | ||
let fonts = collection.register_fonts(blob, None); | ||
|
||
let family_count = fonts.len(); | ||
|
||
// Set up fallbacks for all scripts | ||
for script in fontique::Script::all_samples().iter().map(|(script, _)| *script) { | ||
collection.append_fallbacks( | ||
fontique::FallbackKey::new(script, None), | ||
fonts.iter().map(|(family_id, _)| *family_id), | ||
); | ||
} | ||
|
||
family_count | ||
} | ||
|
||
/// Font metrics in design space. Scale with desired pixel size and divided by units_per_em | ||
/// to obtain pixel metrics. | ||
#[derive(Clone)] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -62,6 +62,12 @@ pub mod window; | |
#[doc(inline)] | ||
pub use string::SharedString; | ||
|
||
/// Register a font from memory. | ||
#[cfg(feature = "shared-fontique")] | ||
pub fn register_font_from_memory(font_data: alloc::vec::Vec<u8>) -> usize { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is just a re-export, it can be done with |
||
i_slint_common::sharedfontique::register_font_from_memory(font_data) | ||
} | ||
|
||
#[doc(inline)] | ||
pub use sharedvector::SharedVector; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this feature is meant to be internal , it should not be documented and have a name that shows it.
Example: https://github.com/slint-ui/slint/blob/55a45a6c339223a19bcd79fc191e79193f495a79/api/rs/build/Cargo.toml#L28C1-L28C14
Maybe something like
experimental-register-font
But actually, i'd rather not have experimental API like this enabled from the slint crate, but directly on the i-slint-core crate, and have app that want to use internal API to use the i-slint-core directly.