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-script = "0.5.5"
|
||||
unicode-segmentation = "1.10.1"
|
||||
rayon = { version = "1", optional = true }
|
||||
|
||||
[dependencies.unicode-bidi]
|
||||
version = "0.3.13"
|
||||
|
|
@ -35,7 +36,7 @@ default-features = false
|
|||
features = ["hardcoded-data"]
|
||||
|
||||
[features]
|
||||
default = ["std", "swash", "fontconfig"]
|
||||
default = ["std", "swash", "fontconfig", "rayon"]
|
||||
fontconfig = ["fontdb/fontconfig", "std"]
|
||||
no_std = ["rustybuzz/libm", "hashbrown"]
|
||||
shape-run-cache = []
|
||||
|
|
@ -50,6 +51,7 @@ std = [
|
|||
vi = ["modit", "syntect", "cosmic_undo_2"]
|
||||
wasm-web = ["sys-locale?/js"]
|
||||
warn_on_missing_glyphs = []
|
||||
rayon = ["dep:rayon"]
|
||||
|
||||
[[bench]]
|
||||
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")]
|
||||
shape_run_cache: crate::ShapeRunCache::default(),
|
||||
};
|
||||
|
||||
ret.cache_fonts(cloned_monospace_font_ids.clone());
|
||||
cloned_monospace_font_ids.into_iter().for_each(|id| {
|
||||
if let Some(font) = ret.get_font(id) {
|
||||
font.scripts().iter().copied().for_each(|script| {
|
||||
|
|
@ -211,6 +211,45 @@ impl FontSystem {
|
|||
pub fn into_locale_and_db(self) -> (String, fontdb::Database) {
|
||||
(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.
|
||||
pub fn get_font(&mut self, id: fontdb::ID) -> Option<Arc<Font>> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue