feat: concurrently load & parse fonts
This commit is contained in:
parent
5e82de11cf
commit
658025314c
3 changed files with 66 additions and 2 deletions
|
|
@ -28,6 +28,7 @@ ttf-parser = { version = "0.20.0", default-features = false }
|
||||||
unicode-linebreak = "0.1.5"
|
unicode-linebreak = "0.1.5"
|
||||||
unicode-script = "0.5.5"
|
unicode-script = "0.5.5"
|
||||||
unicode-segmentation = "1.10.1"
|
unicode-segmentation = "1.10.1"
|
||||||
|
rayon = { version = "1", optional = true }
|
||||||
|
|
||||||
[dependencies.unicode-bidi]
|
[dependencies.unicode-bidi]
|
||||||
version = "0.3.13"
|
version = "0.3.13"
|
||||||
|
|
@ -35,7 +36,7 @@ default-features = false
|
||||||
features = ["hardcoded-data"]
|
features = ["hardcoded-data"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["std", "swash", "fontconfig"]
|
default = ["std", "swash", "fontconfig", "rayon"]
|
||||||
fontconfig = ["fontdb/fontconfig", "std"]
|
fontconfig = ["fontdb/fontconfig", "std"]
|
||||||
no_std = ["rustybuzz/libm", "hashbrown"]
|
no_std = ["rustybuzz/libm", "hashbrown"]
|
||||||
shape-run-cache = []
|
shape-run-cache = []
|
||||||
|
|
@ -50,6 +51,7 @@ std = [
|
||||||
vi = ["modit", "syntect", "cosmic_undo_2"]
|
vi = ["modit", "syntect", "cosmic_undo_2"]
|
||||||
wasm-web = ["sys-locale?/js"]
|
wasm-web = ["sys-locale?/js"]
|
||||||
warn_on_missing_glyphs = []
|
warn_on_missing_glyphs = []
|
||||||
|
rayon = ["dep:rayon"]
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "layout"
|
name = "layout"
|
||||||
|
|
|
||||||
|
|
@ -158,3 +158,26 @@ impl Font {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test{
|
||||||
|
#[test]
|
||||||
|
fn test_fonts_load_time(){
|
||||||
|
use crate::FontSystem;
|
||||||
|
use sys_locale::get_locale;
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
let now = std::time::Instant::now();
|
||||||
|
|
||||||
|
let mut db = fontdb::Database::new();
|
||||||
|
let locale = get_locale().unwrap();
|
||||||
|
db.load_system_fonts();
|
||||||
|
FontSystem::new_with_locale_and_db(locale, db);
|
||||||
|
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
println!(
|
||||||
|
"Fonts load time {}ms.",
|
||||||
|
now.elapsed().as_millis()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -172,7 +172,7 @@ impl FontSystem {
|
||||||
#[cfg(feature = "shape-run-cache")]
|
#[cfg(feature = "shape-run-cache")]
|
||||||
shape_run_cache: crate::ShapeRunCache::default(),
|
shape_run_cache: crate::ShapeRunCache::default(),
|
||||||
};
|
};
|
||||||
|
ret.cache_fonts(cloned_monospace_font_ids.clone());
|
||||||
cloned_monospace_font_ids.into_iter().for_each(|id| {
|
cloned_monospace_font_ids.into_iter().for_each(|id| {
|
||||||
if let Some(font) = ret.get_font(id) {
|
if let Some(font) = ret.get_font(id) {
|
||||||
font.scripts().iter().copied().for_each(|script| {
|
font.scripts().iter().copied().for_each(|script| {
|
||||||
|
|
@ -211,6 +211,45 @@ impl FontSystem {
|
||||||
pub fn into_locale_and_db(self) -> (String, fontdb::Database) {
|
pub fn into_locale_and_db(self) -> (String, fontdb::Database) {
|
||||||
(self.locale, self.db)
|
(self.locale, self.db)
|
||||||
}
|
}
|
||||||
|
/// Concurrently cache fonts by id list
|
||||||
|
pub fn cache_fonts(&mut self, mut ids: Vec<fontdb::ID>) {
|
||||||
|
#[cfg(feature = "rayon")]
|
||||||
|
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
|
||||||
|
ids = ids
|
||||||
|
.into_iter()
|
||||||
|
.filter(|id| {
|
||||||
|
let contains = self.font_cache.contains_key(id);
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
unsafe {
|
||||||
|
self.db.make_shared_face_data(*id);
|
||||||
|
}
|
||||||
|
!contains
|
||||||
|
})
|
||||||
|
.collect::<_>();
|
||||||
|
|
||||||
|
#[cfg(feature = "rayon")]
|
||||||
|
let fonts = ids.par_iter();
|
||||||
|
#[cfg(not(feature = "rayon"))]
|
||||||
|
let fonts = ids.iter();
|
||||||
|
|
||||||
|
fonts
|
||||||
|
.map(|id| match Font::new(&self.db, *id) {
|
||||||
|
Some(font) => Some(Arc::new(font)),
|
||||||
|
None => {
|
||||||
|
log::warn!(
|
||||||
|
"failed to load font '{}'",
|
||||||
|
self.db.face(*id)?.post_script_name
|
||||||
|
);
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Vec<Option<Arc<Font>>>>()
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.for_each(|font| {
|
||||||
|
self.font_cache.insert(font.id, Some(font));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a font by its ID.
|
/// Get a font by its ID.
|
||||||
pub fn get_font(&mut self, id: fontdb::ID) -> Option<Arc<Font>> {
|
pub fn get_font(&mut self, id: fontdb::ID) -> Option<Arc<Font>> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue