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.line.get(),
|
||||||
self.cursor.index,
|
self.cursor.index,
|
||||||
font_opt.map_or("?", |font| font.info.family.as_str()),
|
font_opt.as_ref().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.post_script_name.as_str()),
|
||||||
text_glyph,
|
text_glyph,
|
||||||
text_glyph
|
text_glyph
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
use unicode_script::Script;
|
use unicode_script::Script;
|
||||||
|
|
||||||
use super::Font;
|
use crate::Font;
|
||||||
|
|
||||||
use self::platform::*;
|
use self::platform::*;
|
||||||
|
|
||||||
|
|
@ -27,7 +28,7 @@ mod platform;
|
||||||
mod platform;
|
mod platform;
|
||||||
|
|
||||||
pub struct FontFallbackIter<'a> {
|
pub struct FontFallbackIter<'a> {
|
||||||
fonts: &'a [Font<'a>],
|
fonts: &'a [Arc<Font<'a>>],
|
||||||
default_families: &'a [&'a str],
|
default_families: &'a [&'a str],
|
||||||
default_i: usize,
|
default_i: usize,
|
||||||
scripts: Vec<Script>,
|
scripts: Vec<Script>,
|
||||||
|
|
@ -39,7 +40,12 @@ pub struct FontFallbackIter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> 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 {
|
Self {
|
||||||
fonts,
|
fonts,
|
||||||
default_families,
|
default_families,
|
||||||
|
|
@ -84,7 +90,7 @@ impl<'a> FontFallbackIter<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for 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> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
while self.default_i < self.default_families.len() {
|
while self.default_i < self.default_families.len() {
|
||||||
let default_family = self.default_families[self.default_i];
|
let default_family = self.default_families[self.default_i];
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
use unicode_script::{Script, UnicodeScript};
|
use unicode_script::{Script, UnicodeScript};
|
||||||
|
|
||||||
use super::{Font, FontShapeGlyph, FontShapeLine, FontShapeSpan, FontShapeWord};
|
use super::{Font, FontShapeGlyph, FontShapeLine, FontShapeSpan, FontShapeWord};
|
||||||
|
|
@ -8,13 +9,13 @@ use super::fallback::{FontFallbackIter};
|
||||||
/// Fonts that match a pattern
|
/// Fonts that match a pattern
|
||||||
pub struct FontMatches<'a> {
|
pub struct FontMatches<'a> {
|
||||||
pub locale: &'a str,
|
pub locale: &'a str,
|
||||||
pub fonts: Vec<Font<'a>>,
|
pub fonts: Vec<Arc<Font<'a>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> FontMatches<'a> {
|
impl<'a> FontMatches<'a> {
|
||||||
fn shape_fallback(
|
fn shape_fallback(
|
||||||
&self,
|
&self,
|
||||||
font: &'a Font<'a>,
|
font: &Font<'a>,
|
||||||
line: &str,
|
line: &str,
|
||||||
start_word: usize,
|
start_word: usize,
|
||||||
end_word: usize,
|
end_word: usize,
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
// SPDX-License-Identifier: MIT OR Apache-2.0
|
// SPDX-License-Identifier: MIT OR Apache-2.0
|
||||||
|
|
||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{Attrs, Font, FontMatches};
|
use crate::{Attrs, Font, FontMatches};
|
||||||
|
|
||||||
/// Access system fonts
|
/// Access system fonts
|
||||||
pub struct FontSystem {
|
pub struct FontSystem<'a> {
|
||||||
pub locale: String,
|
pub locale: String,
|
||||||
db: fontdb::Database,
|
db: fontdb::Database,
|
||||||
|
pub font_cache: Mutex<HashMap<fontdb::ID, Option<Arc<Font<'a>>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FontSystem {
|
impl<'a> FontSystem<'a> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let locale = sys_locale::get_locale().unwrap_or_else(|| {
|
let locale = sys_locale::get_locale().unwrap_or_else(|| {
|
||||||
log::warn!("failed to get system locale, falling back to en-US");
|
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>(
|
pub fn matches<F: Fn(&fontdb::FaceInfo) -> bool>(
|
||||||
&self,
|
&'a self,
|
||||||
f: F,
|
f: F,
|
||||||
) -> Option<FontMatches<'_>> {
|
) -> Option<FontMatches<'_>> {
|
||||||
let mut fonts = Vec::new();
|
let mut fonts = Vec::new();
|
||||||
|
|
@ -63,11 +87,9 @@ impl FontSystem {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
match Font::new(face) {
|
match self.get_font(face.id) {
|
||||||
Some(font) => fonts.push(font),
|
Some(font) => fonts.push(font),
|
||||||
None => {
|
None => (),
|
||||||
log::warn!("failed to load font '{}'", face.post_script_name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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| {
|
self.matches(|info| {
|
||||||
let matched = {
|
let matched = {
|
||||||
info.style == attrs.style &&
|
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