From 98336bfafb947f0b4d55a79c422b915bb417c185 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 22 Mar 2021 14:08:50 +0100 Subject: =?UTF-8?q?Better=20font=20family=20definitions=20=E2=9C=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/exec/context.rs | 5 ++-- src/exec/state.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 73 insertions(+), 13 deletions(-) (limited to 'src/exec') 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, + /// A list of font families with generic class definitions. + pub families: Rc, /// 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, + /// Definition of serif font families. + pub serif: Vec, + /// Definition of sans-serif font families. + pub sans_serif: Vec, + /// Definition of monospace font families used for raw text. + pub monospace: Vec, + /// Base fonts that are tried if the list has no match. + pub base: Vec, +} + +impl FamilyMap { + /// Flat iterator over this map's family names. + pub fn iter(&self) -> impl Iterator { + 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, + }) + } +} -- cgit v1.2.3