Rework font cache to cache on paths
This is done in order to help prevent us from loading the same font face over and over again under separate keys. We still incur the performance hit of doing the fontconfig search each new glyph, but that's unavoidable without more extensive refactoring.
This commit is contained in:
parent
3ad6869967
commit
50f27af643
|
@ -27,7 +27,7 @@ use super::{FontDesc, RasterizedGlyph, Metrics, Size, FontKey, GlyphKey, Weight,
|
||||||
pub struct FreeTypeRasterizer {
|
pub struct FreeTypeRasterizer {
|
||||||
faces: HashMap<FontKey, Face<'static>>,
|
faces: HashMap<FontKey, Face<'static>>,
|
||||||
library: Library,
|
library: Library,
|
||||||
keys: HashMap<FontDesc, FontKey>,
|
keys: HashMap<::std::path::PathBuf, FontKey>,
|
||||||
dpi_x: u32,
|
dpi_x: u32,
|
||||||
dpi_y: u32,
|
dpi_y: u32,
|
||||||
dpr: f32,
|
dpr: f32,
|
||||||
|
@ -75,15 +75,10 @@ impl ::Rasterize for FreeTypeRasterizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_font(&mut self, desc: &FontDesc, _size: Size) -> Result<FontKey, Error> {
|
fn load_font(&mut self, desc: &FontDesc, _size: Size) -> Result<FontKey, Error> {
|
||||||
self.keys
|
let face = self.get_face(desc)?;
|
||||||
.get(&desc.to_owned())
|
let key = FontKey::next();
|
||||||
.map(|k| Ok(*k))
|
self.faces.insert(key, face);
|
||||||
.unwrap_or_else(|| {
|
Ok(key)
|
||||||
let face = self.get_face(desc)?;
|
|
||||||
let key = FontKey::next();
|
|
||||||
self.faces.insert(key, face);
|
|
||||||
Ok(key)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_glyph(&mut self, glyph_key: &GlyphKey) -> Result<RasterizedGlyph, Error> {
|
fn get_glyph(&mut self, glyph_key: &GlyphKey) -> Result<RasterizedGlyph, Error> {
|
||||||
|
@ -246,11 +241,26 @@ impl FreeTypeRasterizer {
|
||||||
match fc::font_match(config, &mut pattern) {
|
match fc::font_match(config, &mut pattern) {
|
||||||
Some(font) => {
|
Some(font) => {
|
||||||
if let (Some(path), Some(index)) = (font.file(0), font.index(0)) {
|
if let (Some(path), Some(index)) = (font.file(0), font.index(0)) {
|
||||||
let face = self.library.new_face(path, index)?;
|
match self.keys.get(&path.to_path_buf()) {
|
||||||
let key = FontKey::next();
|
// We've previously loaded this font, so don't
|
||||||
self.faces.insert(key, face);
|
// load it again.
|
||||||
return Ok(key)
|
Some(&key) => {
|
||||||
|
debug!("Hit for font {:?}", path);
|
||||||
|
return Ok(key)
|
||||||
|
},
|
||||||
|
|
||||||
|
None => {
|
||||||
|
debug!("Miss for font {:?}", path);
|
||||||
|
let pathbuf = path.to_path_buf();
|
||||||
|
let face = self.library.new_face(path, index)?;
|
||||||
|
let key = FontKey::next();
|
||||||
|
self.keys.insert(pathbuf, key);
|
||||||
|
self.faces.insert(key, face);
|
||||||
|
return Ok(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(Error::MissingFont(
|
Err(Error::MissingFont(
|
||||||
FontDesc::new("fallback-without-path", Style::Specific(glyph.to_string()))
|
FontDesc::new("fallback-without-path", Style::Specific(glyph.to_string()))
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in New Issue