mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-02 04:48:27 +00:00
Speed up SDF generation
Using Rayon shaves off ~10% off of gallery.slint on my M3.
This commit is contained in:
parent
d8ab4e4600
commit
0ebcbbecbe
4 changed files with 35 additions and 32 deletions
|
|
@ -159,7 +159,7 @@ ttf-parser = { version = "0.21" }
|
|||
# web-sys needs to be >= 0.3.72 for set_fill_style_str
|
||||
web-sys = { version = "0.3.72", default-features = false }
|
||||
smol_str = { version = "0.3.1" }
|
||||
|
||||
rayon = { version = "1.10.0", default-features = false }
|
||||
raw-window-handle-06 = { package = "raw-window-handle", version = "0.6", features = ["alloc"] }
|
||||
|
||||
[profile.release]
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ display-diagnostics = ["codemap", "codemap-diagnostic"]
|
|||
# Enabled the support to render images and font in the binary
|
||||
software-renderer = ["image", "dep:resvg", "fontdue", "i-slint-common/shared-fontdb"]
|
||||
|
||||
embed-glyphs-as-sdf = ["dep:fdsm", "dep:ttf-parser-fdsm", "dep:nalgebra", "dep:image-fdsm"]
|
||||
embed-glyphs-as-sdf = ["dep:fdsm", "dep:ttf-parser-fdsm", "dep:nalgebra", "dep:image-fdsm", "dep:rayon"]
|
||||
|
||||
default = []
|
||||
|
||||
|
|
@ -64,10 +64,11 @@ fdsm = { version = "0.6.0", optional = true, features = ["ttf-parser"]}
|
|||
ttf-parser-fdsm = { package = "ttf-parser", version = "0.24.1", optional = true }
|
||||
image-fdsm = { package = "image", version = "0.25", optional = true, default-features = false }
|
||||
nalgebra = { version = "0.33.0", optional = true }
|
||||
rayon = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
i-slint-parser-test-macro = { path = "./parser-test-macro" }
|
||||
|
||||
regex = "1.3.7"
|
||||
spin_on = { workspace = true }
|
||||
rayon = "1.5.3"
|
||||
rayon = { workspace = true }
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ pub type FontCache = Rc<
|
|||
RefCell<
|
||||
std::collections::HashMap<
|
||||
i_slint_common::sharedfontdb::fontdb::ID,
|
||||
fontdue::FontResult<(Rc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)>,
|
||||
fontdue::FontResult<(Arc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)>,
|
||||
>,
|
||||
>,
|
||||
>;
|
||||
|
|
@ -227,7 +227,7 @@ impl CompilerConfiguration {
|
|||
fn load_font_by_id(
|
||||
&self,
|
||||
face_id: i_slint_common::sharedfontdb::fontdb::ID,
|
||||
) -> fontdue::FontResult<(Rc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)> {
|
||||
) -> fontdue::FontResult<(Arc<fontdue::Font>, Arc<dyn AsRef<[u8]> + Send + Sync>, u32)> {
|
||||
self.font_cache
|
||||
.borrow_mut()
|
||||
.entry(face_id)
|
||||
|
|
@ -246,7 +246,7 @@ impl CompilerConfiguration {
|
|||
)
|
||||
.map(|fontdue_font| {
|
||||
(
|
||||
Rc::new(fontdue_font),
|
||||
Arc::new(fontdue_font),
|
||||
Arc::new(font_data.to_vec())
|
||||
as Arc<dyn AsRef<[u8]> + Send + Sync>,
|
||||
face_index,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use i_slint_common::sharedfontdb::{self, fontdb};
|
|||
struct Font {
|
||||
id: fontdb::ID,
|
||||
#[deref]
|
||||
fontdue_font: Rc<fontdue::Font>,
|
||||
fontdue_font: Arc<fontdue::Font>,
|
||||
face_data: Arc<dyn AsRef<[u8]> + Send + Sync>,
|
||||
face_index: u32,
|
||||
}
|
||||
|
|
@ -442,6 +442,8 @@ fn embed_sdf_glyphs(
|
|||
font: &Font,
|
||||
fallback_fonts: &[Font],
|
||||
) -> Vec<BitmapGlyphs> {
|
||||
use rayon::prelude::*;
|
||||
|
||||
const RANGE: f64 = 6.;
|
||||
|
||||
let Some(max_size) = pixel_sizes.iter().max() else {
|
||||
|
|
@ -450,31 +452,31 @@ fn embed_sdf_glyphs(
|
|||
let min_size = pixel_sizes.iter().min().expect("we have a 'max' so the vector is not empty");
|
||||
let target_pixel_size = (max_size * 2 / 3).max(12).min(RANGE as i16 * min_size);
|
||||
|
||||
let mut glyph_data = Vec::new();
|
||||
|
||||
glyph_data.resize(character_map.len(), Default::default());
|
||||
|
||||
for CharacterMapEntry { code_point, glyph_index } in character_map {
|
||||
let glyph = core::iter::once(font)
|
||||
.chain(fallback_fonts.iter())
|
||||
.find_map(|font| {
|
||||
(font.lookup_glyph_index(*code_point) != 0)
|
||||
.then(|| generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE))
|
||||
})
|
||||
.unwrap_or_else(|| generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE))
|
||||
.map(|(metrics, bitmap)| BitmapGlyph {
|
||||
x: i16::try_from(metrics.xmin).expect("large glyph x coordinate"),
|
||||
y: i16::try_from(metrics.ymin).expect("large glyph y coordinate"),
|
||||
width: i16::try_from(metrics.width).expect("large width"),
|
||||
height: i16::try_from(metrics.height).expect("large height"),
|
||||
x_advance: i16::try_from(metrics.advance_width as i64)
|
||||
.expect("large advance width"),
|
||||
data: bitmap,
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
glyph_data[*glyph_index as usize] = glyph;
|
||||
}
|
||||
let glyph_data = character_map
|
||||
.par_iter()
|
||||
.map(|CharacterMapEntry { code_point, .. }| {
|
||||
core::iter::once(font)
|
||||
.chain(fallback_fonts.iter())
|
||||
.find_map(|font| {
|
||||
(font.lookup_glyph_index(*code_point) != 0).then(|| {
|
||||
generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE)
|
||||
})
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
generate_sdf_for_glyph(font, *code_point, target_pixel_size, RANGE)
|
||||
})
|
||||
.map(|(metrics, bitmap)| BitmapGlyph {
|
||||
x: i16::try_from(metrics.xmin).expect("large glyph x coordinate"),
|
||||
y: i16::try_from(metrics.ymin).expect("large glyph y coordinate"),
|
||||
width: i16::try_from(metrics.width).expect("large width"),
|
||||
height: i16::try_from(metrics.height).expect("large height"),
|
||||
x_advance: i16::try_from(metrics.advance_width as i64)
|
||||
.expect("large advance width"),
|
||||
data: bitmap,
|
||||
})
|
||||
.unwrap_or_default()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
vec![BitmapGlyphs { pixel_size: target_pixel_size, glyph_data }]
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue