From af014cfe5eea4233d8034c79c1a5f898c972396c Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 7 Jan 2022 10:46:55 +0100 Subject: Tidy up styling --- src/eval/class.rs | 2 +- src/eval/node.rs | 27 +++++++++++++++++++++++---- src/eval/styles.rs | 18 +++++++++--------- 3 files changed, 33 insertions(+), 14 deletions(-) (limited to 'src/eval') diff --git a/src/eval/class.rs b/src/eval/class.rs index 7888cba2..b7b4d012 100644 --- a/src/eval/class.rs +++ b/src/eval/class.rs @@ -66,7 +66,7 @@ impl Class { let mut styles = StyleMap::new(); self.set(args, &mut styles)?; let node = (self.construct)(ctx, args)?; - Ok(node.styled(styles)) + Ok(node.styled_with_map(styles)) } /// Execute the class's set rule. diff --git a/src/eval/node.rs b/src/eval/node.rs index 2c955d01..37f230ee 100644 --- a/src/eval/node.rs +++ b/src/eval/node.rs @@ -5,7 +5,7 @@ use std::iter::Sum; use std::mem; use std::ops::{Add, AddAssign}; -use super::{StyleMap, Styled}; +use super::{Property, StyleMap, Styled}; use crate::diag::StrResult; use crate::geom::SpecAxis; use crate::layout::{Layout, PackedNode, RootNode}; @@ -84,14 +84,33 @@ impl Node { Self::Block(node.pack()) } - /// Style this node. - pub fn styled(self, styles: StyleMap) -> Self { + /// Style this node with a single property. + pub fn styled(mut self, key: P, value: P::Value) -> Self { + if let Self::Sequence(vec) = &mut self { + if let [styled] = vec.as_mut_slice() { + styled.map.set(key, value); + return self; + } + } + + self.styled_with_map(StyleMap::with(key, value)) + } + + /// Style this node with a full style map. + pub fn styled_with_map(mut self, styles: StyleMap) -> Self { + if let Self::Sequence(vec) = &mut self { + if let [styled] = vec.as_mut_slice() { + styled.map.apply(&styles); + return self; + } + } + Self::Sequence(vec![Styled::new(self, styles)]) } /// Style this node in monospace. pub fn monospaced(self) -> Self { - self.styled(StyleMap::with(TextNode::MONOSPACE, true)) + self.styled(TextNode::MONOSPACE, true) } /// Lift to a type-erased block-level node. diff --git a/src/eval/styles.rs b/src/eval/styles.rs index 54ac2697..0f3d694a 100644 --- a/src/eval/styles.rs +++ b/src/eval/styles.rs @@ -106,7 +106,6 @@ impl StyleMap { /// `outer`. The ones from `self` take precedence over the ones from /// `outer`. For folded properties `self` contributes the inner value. pub fn chain<'a>(&'a self, outer: &'a StyleChain<'a>) -> StyleChain<'a> { - // No need to chain an empty map. if self.is_empty() { *outer } else { @@ -182,7 +181,9 @@ impl PartialEq for StyleMap { /// matches further up the chain. #[derive(Clone, Copy, Hash)] pub struct StyleChain<'a> { + /// The first map in the chain. inner: &'a StyleMap, + /// The remaining maps in the chain. outer: Option<&'a Self>, } @@ -238,14 +239,13 @@ impl<'a> StyleChain<'a> { /// entry for it. pub fn get_cloned(self, key: P) -> P::Value { if let Some(value) = self.find(key).cloned() { - if P::FOLDABLE { - if let Some(outer) = self.outer { - P::fold(value, outer.get_cloned(key)) - } else { - P::fold(value, P::default()) - } - } else { - value + if !P::FOLDABLE { + return value; + } + + match self.outer { + Some(outer) => P::fold(value, outer.get_cloned(key)), + None => P::fold(value, P::default()), } } else if let Some(outer) = self.outer { outer.get_cloned(key) -- cgit v1.2.3