Fix caching of variable font faces
This commit is contained in:
parent
33cabfc3d2
commit
de5d770416
|
@ -41,7 +41,7 @@ pub mod char_set;
|
||||||
pub use char_set::{CharSet, CharSetRef};
|
pub use char_set::{CharSet, CharSetRef};
|
||||||
|
|
||||||
pub mod pattern;
|
pub mod pattern;
|
||||||
pub use pattern::{Pattern, PatternHash, PatternRef};
|
pub use pattern::{FTFaceLocation, Pattern, PatternHash, PatternRef};
|
||||||
|
|
||||||
/// Find the font closest matching the provided pattern.
|
/// Find the font closest matching the provided pattern.
|
||||||
///
|
///
|
||||||
|
|
|
@ -356,6 +356,18 @@ macro_rules! string_accessor {
|
||||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
pub struct PatternHash(pub u32);
|
pub struct PatternHash(pub u32);
|
||||||
|
|
||||||
|
#[derive(Hash, Eq, PartialEq, Debug)]
|
||||||
|
pub struct FTFaceLocation {
|
||||||
|
pub path: PathBuf,
|
||||||
|
pub index: isize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FTFaceLocation {
|
||||||
|
pub fn new(path: PathBuf, index: isize) -> Self {
|
||||||
|
Self { path, index }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Pattern {
|
impl Pattern {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
|
@ -583,6 +595,13 @@ impl PatternRef {
|
||||||
unsafe { self.get_string(b"file\0").nth(index) }.map(From::from)
|
unsafe { self.get_string(b"file\0").nth(index) }.map(From::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ft_face_location(&self, index: usize) -> Option<FTFaceLocation> {
|
||||||
|
match (self.file(index), self.index().next()) {
|
||||||
|
(Some(path), Some(index)) => Some(FTFaceLocation::new(path, index)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn config_substitute(&mut self, config: &ConfigRef, kind: MatchKind) {
|
pub fn config_substitute(&mut self, config: &ConfigRef, kind: MatchKind) {
|
||||||
unsafe {
|
unsafe {
|
||||||
FcConfigSubstitute(config.as_ptr(), self.as_ptr(), kind as u32);
|
FcConfigSubstitute(config.as_ptr(), self.as_ptr(), kind as u32);
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
use std::cmp::{min, Ordering};
|
use std::cmp::{min, Ordering};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::{self, Display, Formatter};
|
use std::fmt::{self, Display, Formatter};
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use freetype::tt_os2::TrueTypeOS2Table;
|
use freetype::tt_os2::TrueTypeOS2Table;
|
||||||
|
@ -27,7 +26,7 @@ use log::{debug, trace};
|
||||||
|
|
||||||
pub mod fc;
|
pub mod fc;
|
||||||
|
|
||||||
use fc::{CharSet, Pattern, PatternHash, PatternRef};
|
use fc::{CharSet, FTFaceLocation, Pattern, PatternHash, PatternRef};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
BitmapBuffer, FontDesc, FontKey, GlyphKey, Metrics, Rasterize, RasterizedGlyph, Size, Slant,
|
BitmapBuffer, FontDesc, FontKey, GlyphKey, Metrics, Rasterize, RasterizedGlyph, Size, Slant,
|
||||||
|
@ -90,7 +89,7 @@ impl fmt::Debug for FaceLoadingProperties {
|
||||||
pub struct FreeTypeRasterizer {
|
pub struct FreeTypeRasterizer {
|
||||||
library: Library,
|
library: Library,
|
||||||
faces: HashMap<FontKey, FaceLoadingProperties>,
|
faces: HashMap<FontKey, FaceLoadingProperties>,
|
||||||
ft_faces: HashMap<PathBuf, Rc<FTFace>>,
|
ft_faces: HashMap<FTFaceLocation, Rc<FTFace>>,
|
||||||
fallback_lists: HashMap<FontKey, FallbackList>,
|
fallback_lists: HashMap<FontKey, FallbackList>,
|
||||||
device_pixel_ratio: f32,
|
device_pixel_ratio: f32,
|
||||||
}
|
}
|
||||||
|
@ -294,8 +293,8 @@ impl FreeTypeRasterizer {
|
||||||
Ok(FullMetrics { size_metrics, cell_width: width })
|
Ok(FullMetrics { size_metrics, cell_width: width })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_ft_face(&mut self, path: PathBuf, index: isize) -> Result<Rc<FTFace>, Error> {
|
fn load_ft_face(&mut self, ft_face_location: FTFaceLocation) -> Result<Rc<FTFace>, Error> {
|
||||||
let mut ft_face = self.library.new_face(&path, index)?;
|
let mut ft_face = self.library.new_face(&ft_face_location.path, ft_face_location.index)?;
|
||||||
if ft_face.has_color() {
|
if ft_face.has_color() {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Select the colored bitmap size to use from the array of available sizes
|
// Select the colored bitmap size to use from the array of available sizes
|
||||||
|
@ -304,7 +303,7 @@ impl FreeTypeRasterizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
let ft_face = Rc::new(ft_face);
|
let ft_face = Rc::new(ft_face);
|
||||||
self.ft_faces.insert(path, Rc::clone(&ft_face));
|
self.ft_faces.insert(ft_face_location, Rc::clone(&ft_face));
|
||||||
|
|
||||||
Ok(ft_face)
|
Ok(ft_face)
|
||||||
}
|
}
|
||||||
|
@ -314,16 +313,16 @@ impl FreeTypeRasterizer {
|
||||||
pattern: &PatternRef,
|
pattern: &PatternRef,
|
||||||
font_key: FontKey,
|
font_key: FontKey,
|
||||||
) -> Result<Option<FontKey>, Error> {
|
) -> Result<Option<FontKey>, Error> {
|
||||||
if let (Some(path), Some(index)) = (pattern.file(0), pattern.index().next()) {
|
if let Some(ft_face_location) = pattern.ft_face_location(0) {
|
||||||
if self.faces.get(&font_key).is_some() {
|
if self.faces.get(&font_key).is_some() {
|
||||||
return Ok(Some(font_key));
|
return Ok(Some(font_key));
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("Got font path={:?}", path);
|
trace!("Got font path={:?}, index={:?}", ft_face_location.path, ft_face_location.index);
|
||||||
|
|
||||||
let ft_face = match self.ft_faces.get(&path) {
|
let ft_face = match self.ft_faces.get(&ft_face_location) {
|
||||||
Some(ft_face) => Rc::clone(ft_face),
|
Some(ft_face) => Rc::clone(ft_face),
|
||||||
None => self.load_ft_face(path, index)?,
|
None => self.load_ft_face(ft_face_location)?,
|
||||||
};
|
};
|
||||||
|
|
||||||
let non_scalable = if pattern.scalable().next().unwrap_or(true) {
|
let non_scalable = if pattern.scalable().next().unwrap_or(true) {
|
||||||
|
|
Loading…
Reference in New Issue