summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-08-26 17:05:37 +0200
committerLaurenz <laurmaedje@gmail.com>2021-08-27 14:08:31 +0200
commit7eeafbd4645789b92e25a7d1922410a50cbf49a6 (patch)
treec10c552fff3f3d7ac2c42ebfa7366b12133e36ab /src
parent0001a965d7c2a8f66411e3f0b841f8844b0151b6 (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.rs3
-rw-r--r--src/font.rs34
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)]