Cache fonts
This commit is contained in:
parent
c60aaaf9d2
commit
324c8837fd
4 changed files with 46 additions and 23 deletions
|
|
@ -829,8 +829,8 @@ impl<'a> TextBuffer<'a> {
|
|||
"{}, {}: '{}' ('{}'): '{}' ({:?})",
|
||||
self.cursor.line.get(),
|
||||
self.cursor.index,
|
||||
font_opt.map_or("?", |font| font.info.family.as_str()),
|
||||
font_opt.map_or("?", |font| font.info.post_script_name.as_str()),
|
||||
font_opt.as_ref().map_or("?", |font| font.info.family.as_str()),
|
||||
font_opt.as_ref().map_or("?", |font| font.info.post_script_name.as_str()),
|
||||
text_glyph,
|
||||
text_glyph
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use std::sync::Arc;
|
||||
use unicode_script::Script;
|
||||
|
||||
use super::Font;
|
||||
use crate::Font;
|
||||
|
||||
use self::platform::*;
|
||||
|
||||
|
|
@ -27,7 +28,7 @@ mod platform;
|
|||
mod platform;
|
||||
|
||||
pub struct FontFallbackIter<'a> {
|
||||
fonts: &'a [Font<'a>],
|
||||
fonts: &'a [Arc<Font<'a>>],
|
||||
default_families: &'a [&'a str],
|
||||
default_i: usize,
|
||||
scripts: Vec<Script>,
|
||||
|
|
@ -39,7 +40,12 @@ pub struct FontFallbackIter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> FontFallbackIter<'a> {
|
||||
pub fn new(fonts: &'a [Font<'a>], default_families: &'a [&'a str], scripts: Vec<Script>, locale: &'a str) -> Self {
|
||||
pub fn new(
|
||||
fonts: &'a [Arc<Font<'a>>],
|
||||
default_families: &'a [&'a str],
|
||||
scripts: Vec<Script>,
|
||||
locale: &'a str
|
||||
) -> Self {
|
||||
Self {
|
||||
fonts,
|
||||
default_families,
|
||||
|
|
@ -84,7 +90,7 @@ impl<'a> FontFallbackIter<'a> {
|
|||
}
|
||||
|
||||
impl<'a> Iterator for FontFallbackIter<'a> {
|
||||
type Item = &'a Font<'a>;
|
||||
type Item = &'a Arc<Font<'a>>;
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
while self.default_i < self.default_families.len() {
|
||||
let default_family = self.default_families[self.default_i];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use std::sync::Arc;
|
||||
use unicode_script::{Script, UnicodeScript};
|
||||
|
||||
use super::{Font, FontShapeGlyph, FontShapeLine, FontShapeSpan, FontShapeWord};
|
||||
|
|
@ -8,13 +9,13 @@ use super::fallback::{FontFallbackIter};
|
|||
/// Fonts that match a pattern
|
||||
pub struct FontMatches<'a> {
|
||||
pub locale: &'a str,
|
||||
pub fonts: Vec<Font<'a>>,
|
||||
pub fonts: Vec<Arc<Font<'a>>>,
|
||||
}
|
||||
|
||||
impl<'a> FontMatches<'a> {
|
||||
fn shape_fallback(
|
||||
&self,
|
||||
font: &'a Font<'a>,
|
||||
font: &Font<'a>,
|
||||
line: &str,
|
||||
start_word: usize,
|
||||
end_word: usize,
|
||||
|
|
|
|||
|
|
@ -1,14 +1,20 @@
|
|||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
use crate::{Attrs, Font, FontMatches};
|
||||
|
||||
/// Access system fonts
|
||||
pub struct FontSystem {
|
||||
pub struct FontSystem<'a> {
|
||||
pub locale: String,
|
||||
db: fontdb::Database,
|
||||
pub font_cache: Mutex<HashMap<fontdb::ID, Option<Arc<Font<'a>>>>>,
|
||||
}
|
||||
|
||||
impl FontSystem {
|
||||
impl<'a> FontSystem<'a> {
|
||||
pub fn new() -> Self {
|
||||
let locale = sys_locale::get_locale().unwrap_or_else(|| {
|
||||
log::warn!("failed to get system locale, falling back to en-US");
|
||||
|
|
@ -50,11 +56,29 @@ impl FontSystem {
|
|||
);
|
||||
}
|
||||
|
||||
Self { locale, db }
|
||||
Self {
|
||||
locale,
|
||||
db,
|
||||
font_cache: Mutex::new(HashMap::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_font(&'a self, id: fontdb::ID) -> Option<Arc<Font<'a>>> {
|
||||
let mut font_cache = self.font_cache.lock().unwrap();
|
||||
font_cache.entry(id).or_insert_with(|| {
|
||||
let face = self.db.face(id)?;
|
||||
match Font::new(face) {
|
||||
Some(font) => Some(Arc::new(font)),
|
||||
None => {
|
||||
log::warn!("failed to load font '{}'", face.post_script_name);
|
||||
None
|
||||
}
|
||||
}
|
||||
}).clone()
|
||||
}
|
||||
|
||||
pub fn matches<F: Fn(&fontdb::FaceInfo) -> bool>(
|
||||
&self,
|
||||
&'a self,
|
||||
f: F,
|
||||
) -> Option<FontMatches<'_>> {
|
||||
let mut fonts = Vec::new();
|
||||
|
|
@ -63,11 +87,9 @@ impl FontSystem {
|
|||
continue;
|
||||
}
|
||||
|
||||
match Font::new(face) {
|
||||
match self.get_font(face.id) {
|
||||
Some(font) => fonts.push(font),
|
||||
None => {
|
||||
log::warn!("failed to load font '{}'", face.post_script_name);
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -81,7 +103,7 @@ impl FontSystem {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn matches_attrs(&self, attrs: Attrs) -> Option<FontMatches<'_>> {
|
||||
pub fn matches_attrs(&'a self, attrs: Attrs) -> Option<FontMatches<'_>> {
|
||||
self.matches(|info| {
|
||||
let matched = {
|
||||
info.style == attrs.style &&
|
||||
|
|
@ -108,9 +130,3 @@ impl FontSystem {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for FontSystem {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue