diff options
| author | Laurenz <laurmaedje@gmail.com> | 2021-03-22 14:08:50 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2021-03-22 14:08:50 +0100 |
| commit | 98336bfafb947f0b4d55a79c422b915bb417c185 (patch) | |
| tree | bf0ead89a3d7eed3d8bb87d013c2a813633c75e4 /src/exec | |
| parent | 39f55481ed7bc5ebc6d310924e90e7b6c0760d3b (diff) | |
Better font family definitions ✒
Diffstat (limited to 'src/exec')
| -rw-r--r-- | src/exec/context.rs | 5 | ||||
| -rw-r--r-- | src/exec/state.rs | 81 |
2 files changed, 73 insertions, 13 deletions
diff --git a/src/exec/context.rs b/src/exec/context.rs index f19f6561..6ba5b25f 100644 --- a/src/exec/context.rs +++ b/src/exec/context.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use fontdock::FontStyle; -use super::{Exec, State}; +use super::{Exec, FontFamily, State}; use crate::diag::{Diag, DiagSet, Pass}; use crate::env::Env; use crate::eval::TemplateValue; @@ -74,8 +74,7 @@ impl<'a> ExecContext<'a> { /// Set the font to monospace. pub fn set_monospace(&mut self) { let families = self.state.font.families_mut(); - families.list.insert(0, "monospace".to_string()); - families.flatten(); + families.list.insert(0, FontFamily::Monospace); } /// Push a layout node into the active paragraph. diff --git a/src/exec/state.rs b/src/exec/state.rs index f66694fd..0322c437 100644 --- a/src/exec/state.rs +++ b/src/exec/state.rs @@ -1,6 +1,7 @@ +use std::fmt::{self, Display, Formatter}; use std::rc::Rc; -use fontdock::{fallback, FallbackTree, FontStretch, FontStyle, FontVariant, FontWeight}; +use fontdock::{FontStretch, FontStyle, FontVariant, FontWeight}; use crate::color::{Color, RgbaColor}; use crate::geom::*; @@ -98,8 +99,8 @@ impl Default for ParState { /// Defines font properties. #[derive(Debug, Clone, PartialEq)] pub struct FontState { - /// A tree of font family names and generic class names. - pub families: Rc<FallbackTree>, + /// A list of font families with generic class definitions. + pub families: Rc<FamilyMap>, /// The selected font variant. pub variant: FontVariant, /// The font size. @@ -122,7 +123,7 @@ pub struct FontState { impl FontState { /// Access the `families` mutably. - pub fn families_mut(&mut self) -> &mut FallbackTree { + pub fn families_mut(&mut self) -> &mut FamilyMap { Rc::make_mut(&mut self.families) } @@ -135,12 +136,7 @@ impl FontState { impl Default for FontState { fn default() -> Self { Self { - // The default tree of font fallbacks. - families: Rc::new(fallback! { - list: [], - classes: { "monospace" => ["inconsolata"] }, - base: ["eb garamond", "twitter color emoji"], - }), + families: Rc::new(FamilyMap::default()), variant: FontVariant { style: FontStyle::Normal, weight: FontWeight::REGULAR, @@ -156,3 +152,68 @@ impl Default for FontState { } } } + +/// Font family definitions. +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] +pub struct FamilyMap { + /// The user-defined list of font families. + pub list: Vec<FontFamily>, + /// Definition of serif font families. + pub serif: Vec<String>, + /// Definition of sans-serif font families. + pub sans_serif: Vec<String>, + /// Definition of monospace font families used for raw text. + pub monospace: Vec<String>, + /// Base fonts that are tried if the list has no match. + pub base: Vec<String>, +} + +impl FamilyMap { + /// Flat iterator over this map's family names. + pub fn iter(&self) -> impl Iterator<Item = &str> { + self.list + .iter() + .flat_map(move |family: &FontFamily| { + match family { + FontFamily::Named(name) => std::slice::from_ref(name), + FontFamily::Serif => &self.serif, + FontFamily::SansSerif => &self.sans_serif, + FontFamily::Monospace => &self.monospace, + } + }) + .chain(&self.base) + .map(String::as_str) + } +} + +impl Default for FamilyMap { + fn default() -> Self { + Self { + list: vec![FontFamily::Serif], + serif: vec!["eb garamond".into()], + sans_serif: vec![/* TODO */], + monospace: vec!["inconsolata".into()], + base: vec!["twitter color emoji".into()], + } + } +} + +/// A generic or named font family. +#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] +pub enum FontFamily { + Serif, + SansSerif, + Monospace, + Named(String), +} + +impl Display for FontFamily { + fn fmt(&self, f: &mut Formatter) -> fmt::Result { + f.pad(match self { + Self::Serif => "serif", + Self::SansSerif => "sans-serif", + Self::Monospace => "monospace", + Self::Named(s) => s, + }) + } +} |
