diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-08-26 17:05:37 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-08-27 14:08:31 +0200 |
| commit | 7eeafbd4645789b92e25a7d1922410a50cbf49a6 (patch) | |
| tree | c10c552fff3f3d7ac2c42ebfa7366b12133e36ab /src | |
| parent | 0001a965d7c2a8f66411e3f0b841f8844b0151b6 (diff) | |
Font family things
- Better default font family order
- Remove weird leading dots from font family names
- Public API for retrieving all found font families
Diffstat (limited to 'src')
| -rw-r--r-- | src/eval/state.rs | 3 | ||||
| -rw-r--r-- | src/font.rs | 34 |
2 files changed, 28 insertions, 9 deletions
diff --git a/src/eval/state.rs b/src/eval/state.rs index d7ca014d..2037c695 100644 --- a/src/eval/state.rs +++ b/src/eval/state.rs @@ -233,8 +233,9 @@ impl Default for FamilyState { sans_serif: Rc::new(vec!["pt sans".into()]), monospace: Rc::new(vec!["inconsolata".into()]), base: Rc::new(vec![ - "twitter color emoji".into(), + "eb garamond".into(), "latin modern math".into(), + "twitter color emoji".into(), ]), } } diff --git a/src/font.rs b/src/font.rs index 00bff02e..2e935d3b 100644 --- a/src/font.rs +++ b/src/font.rs @@ -1,6 +1,6 @@ //! Font handling. -use std::collections::{hash_map::Entry, HashMap}; +use std::collections::{hash_map::Entry, BTreeMap, HashMap}; use std::fmt::{self, Debug, Display, Formatter}; use std::path::{Path, PathBuf}; use std::rc::Rc; @@ -35,7 +35,7 @@ impl FaceId { pub struct FontStore { loader: Rc<dyn Loader>, faces: Vec<Option<Face>>, - families: HashMap<String, Vec<FaceId>>, + families: BTreeMap<String, Vec<FaceId>>, buffers: HashMap<FileHash, Rc<Vec<u8>>>, on_load: Option<Box<dyn Fn(FaceId, &Face)>>, } @@ -44,15 +44,12 @@ impl FontStore { /// Create a new, empty font store. pub fn new(loader: Rc<dyn Loader>) -> Self { let mut faces = vec![]; - let mut families = HashMap::<String, Vec<FaceId>>::new(); + let mut families = BTreeMap::<String, Vec<FaceId>>::new(); for (i, info) in loader.faces().iter().enumerate() { let id = FaceId(i as u32); faces.push(None); - families - .entry(info.family.to_lowercase()) - .and_modify(|vec| vec.push(id)) - .or_insert_with(|| vec![id]); + families.entry(info.family.to_lowercase()).or_default().push(id); } Self { @@ -146,6 +143,16 @@ impl FontStore { pub fn get(&self, id: FaceId) -> &Face { self.faces[id.0 as usize].as_ref().expect("font face was not loaded") } + + /// Returns an ordered iterator over all font family names this loader + /// knows. + pub fn families(&self) -> impl Iterator<Item = &str> + '_ { + // Since the keys are lowercased, we instead use the family field of the + // first face's info. + self.families + .values() + .map(move |id| self.loader.faces()[id[0].0 as usize].family.as_str()) + } } /// A font face. @@ -356,9 +363,14 @@ impl FaceInfo { (0 .. count).filter_map(move |index| { let face = ttf_parser::Face::from_slice(data, index).ok()?; - let family = find_name(face.names(), name_id::TYPOGRAPHIC_FAMILY) + let mut family = find_name(face.names(), name_id::TYPOGRAPHIC_FAMILY) .or_else(|| find_name(face.names(), name_id::FAMILY))?; + // Remove weird leading dot appearing in some fonts. + if let Some(undotted) = family.strip_prefix('.') { + family = undotted.to_string(); + } + let variant = FontVariant { style: match (face.is_italic(), face.is_oblique()) { (false, false) => FontStyle::Normal, @@ -415,6 +427,12 @@ impl FontVariant { } } +impl Display for FontVariant { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + write!(f, "{}-{}-{}", self.style, self.weight, self.stretch) + } +} + /// The style of a font face. #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Serialize, Deserialize)] |
