From 3330767c20e14a05176902a93dcefb08cb509173 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Fri, 11 Jun 2021 11:30:18 +0200 Subject: Remove props in favor of using state for everything --- src/exec/context.rs | 22 +++++---- src/exec/mod.rs | 13 +++--- src/exec/state.rs | 125 +++++++--------------------------------------------- 3 files changed, 36 insertions(+), 124 deletions(-) (limited to 'src/exec') diff --git a/src/exec/context.rs b/src/exec/context.rs index 63008260..e03a7c67 100644 --- a/src/exec/context.rs +++ b/src/exec/context.rs @@ -1,4 +1,5 @@ use std::mem; +use std::rc::Rc; use super::{Exec, ExecWithMap, FontFamily, State}; use crate::diag::{Diag, DiagSet, Pass}; @@ -43,8 +44,11 @@ impl ExecContext { /// Set the font to monospace. pub fn set_monospace(&mut self) { - let families = self.state.font.families_mut(); - families.list.insert(0, FontFamily::Monospace); + self.state + .font_mut() + .families_mut() + .list + .insert(0, FontFamily::Monospace); } /// Execute a template and return the result as a stack node. @@ -108,8 +112,7 @@ impl ExecContext { /// Apply a forced paragraph break. pub fn parbreak(&mut self) { - let em = self.state.font.resolve_size(); - let amount = self.state.par.spacing.resolve(em); + let amount = self.state.par.spacing.resolve(self.state.font.size); self.stack.parbreak(&self.state); self.stack.push_soft(StackChild::Spacing(amount)); } @@ -133,9 +136,11 @@ impl ExecContext { } fn make_text_node(&self, text: impl Into) -> ParChild { - let align = self.state.aligns.cross; - let props = self.state.font.resolve_props(); - ParChild::Text(text.into(), props, align) + ParChild::Text( + text.into(), + self.state.aligns.cross, + Rc::clone(&self.state.font), + ) } } @@ -217,11 +222,10 @@ struct ParBuilder { impl ParBuilder { fn new(state: &State) -> Self { - let em = state.font.resolve_size(); Self { aligns: state.aligns, dir: state.lang.dir, - line_spacing: state.par.leading.resolve(em), + line_spacing: state.par.leading.resolve(state.font.size), children: vec![], last: Last::None, } diff --git a/src/exec/mod.rs b/src/exec/mod.rs index a13d8c5e..639c1a87 100644 --- a/src/exec/mod.rs +++ b/src/exec/mod.rs @@ -55,8 +55,8 @@ impl ExecWithMap for syntax::Node { Self::Space => ctx.push_word_space(), Self::Linebreak(_) => ctx.linebreak(), Self::Parbreak(_) => ctx.parbreak(), - Self::Strong(_) => ctx.state.font.strong ^= true, - Self::Emph(_) => ctx.state.font.emph ^= true, + Self::Strong(_) => ctx.state.font_mut().strong ^= true, + Self::Emph(_) => ctx.state.font_mut().emph ^= true, Self::Raw(raw) => raw.exec(ctx), Self::Heading(heading) => heading.exec_with_map(ctx, map), Self::List(list) => list.exec_with_map(ctx, map), @@ -85,10 +85,11 @@ impl Exec for syntax::RawNode { impl ExecWithMap for syntax::HeadingNode { fn exec_with_map(&self, ctx: &mut ExecContext, map: &ExprMap) { let snapshot = ctx.state.clone(); + let font = ctx.state.font_mut(); let upscale = 1.6 - 0.1 * self.level as f64; - ctx.state.font.scale *= upscale; - ctx.state.font.strong = true; + font.size *= upscale; + font.strong = true; self.body.exec_with_map(ctx, map); @@ -109,7 +110,7 @@ impl ExecWithMap for syntax::ListNode { aspect: None, children: vec![ StackChild::Any(bullet.into(), Gen::default()), - StackChild::Spacing(ctx.state.font.resolve_size() / 2.0), + StackChild::Spacing(ctx.state.font.size / 2.0), StackChild::Any(body.into(), Gen::default()), ], }; @@ -139,7 +140,7 @@ impl Exec for Value { let prev = Rc::clone(&ctx.state.font.families); ctx.set_monospace(); ctx.push_text(pretty(other)); - ctx.state.font.families = prev; + ctx.state.font_mut().families = prev; } } } diff --git a/src/exec/state.rs b/src/exec/state.rs index 2b824afe..fa16004e 100644 --- a/src/exec/state.rs +++ b/src/exec/state.rs @@ -8,7 +8,7 @@ use crate::layout::Fill; use crate::paper::{Paper, PaperClass, PAPER_A4}; /// The execution state. -#[derive(Debug, Clone, PartialEq)] +#[derive(Default, Debug, Clone, PartialEq, Hash)] pub struct State { /// The current language-related settings. pub lang: LangState, @@ -17,25 +17,20 @@ pub struct State { /// The current paragraph settings. pub par: ParState, /// The current font settings. - pub font: FontState, + pub font: Rc, /// The current alignments of layouts in their parents. pub aligns: Gen, } -impl Default for State { - fn default() -> Self { - Self { - lang: LangState::default(), - page: PageState::default(), - par: ParState::default(), - font: FontState::default(), - aligns: Gen::splat(Align::Start), - } +impl State { + /// Access the `font` state mutably. + pub fn font_mut(&mut self) -> &mut FontState { + Rc::make_mut(&mut self.font) } } /// Defines language properties. -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Hash)] pub struct LangState { /// The direction for text and other inline objects. pub dir: Dir, @@ -48,7 +43,7 @@ impl Default for LangState { } /// Defines page properties. -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Hash)] pub struct PageState { /// The class of this page. pub class: PaperClass, @@ -88,7 +83,7 @@ impl Default for PageState { } /// Defines paragraph properties. -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Hash)] pub struct ParState { /// The spacing between paragraphs (dependent on scaled font size). pub spacing: Linear, @@ -110,7 +105,7 @@ impl Default for ParState { } /// Defines font properties. -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Hash)] pub struct FontState { /// A list of font families with generic class definitions. pub families: Rc, @@ -118,8 +113,6 @@ pub struct FontState { pub variant: FontVariant, /// The font size. pub size: Length, - /// The linear to apply on the base font size. - pub scale: Linear, /// The top end of the text bounding box. pub top_edge: VerticalFontMetric, /// The bottom end of the text bounding box. @@ -133,49 +126,14 @@ pub struct FontState { /// whether the next `_` makes italic or non-italic. pub emph: bool, /// The specifications for a strikethrough line, if any. - pub strikethrough: Option, + pub strikethrough: Option>, /// The specifications for a underline, if any. - pub underline: Option, + pub underline: Option>, /// The specifications for a overline line, if any. - pub overline: Option, + pub overline: Option>, } impl FontState { - /// The resolved font size. - pub fn resolve_size(&self) -> Length { - self.scale.resolve(self.size) - } - - /// Resolve font properties. - pub fn resolve_props(&self) -> FontProps { - let mut variant = self.variant; - - if self.strong { - variant.weight = variant.weight.thicken(300); - } - - if self.emph { - variant.style = match variant.style { - FontStyle::Normal => FontStyle::Italic, - FontStyle::Italic => FontStyle::Normal, - FontStyle::Oblique => FontStyle::Normal, - } - } - - let size = self.resolve_size(); - FontProps { - families: Rc::clone(&self.families), - variant, - size, - top_edge: self.top_edge, - bottom_edge: self.bottom_edge, - strikethrough: self.strikethrough.map(|s| s.resolve_props(size, &self.fill)), - underline: self.underline.map(|s| s.resolve_props(size, &self.fill)), - overline: self.overline.map(|s| s.resolve_props(size, &self.fill)), - fill: self.fill, - } - } - /// Access the `families` mutably. pub fn families_mut(&mut self) -> &mut FamilyList { Rc::make_mut(&mut self.families) @@ -194,7 +152,6 @@ impl Default for FontState { size: Length::pt(11.0), top_edge: VerticalFontMetric::CapHeight, bottom_edge: VerticalFontMetric::Baseline, - scale: Linear::one(), fill: Fill::Color(Color::Rgba(RgbaColor::BLACK)), strong: false, emph: false, @@ -205,11 +162,9 @@ impl Default for FontState { } } -/// Describes a line that could be positioned over or under text. +/// Describes a line that could be positioned over, under or on top of text. #[derive(Debug, Copy, Clone, PartialEq, Hash)] pub struct LineState { - /// Color of the line. Will default to text color if `None`. - pub fill: Option, /// Thickness of the line's stroke. Calling functions should attempt to /// read this value from the appropriate font tables if this is `None`. pub strength: Option, @@ -219,40 +174,8 @@ pub struct LineState { pub position: Option, /// Amount that the line will be longer or shorter than its associated text. pub extent: Linear, -} - -impl LineState { - pub fn resolve_props(&self, font_size: Length, fill: &Fill) -> LineProps { - LineProps { - fill: self.fill.unwrap_or_else(|| fill.clone()), - strength: self.strength.map(|s| s.resolve(font_size)), - position: self.position.map(|p| p.resolve(font_size)), - extent: self.extent.resolve(font_size), - } - } -} - -/// Properties used for font selection and layout. -#[derive(Debug, Clone, PartialEq, Hash)] -pub struct FontProps { - /// The list of font families to use for shaping. - pub families: Rc, - /// Which variant of the font to use. - pub variant: FontVariant, - /// The font size. - pub size: Length, - /// What line to consider the top edge of text. - pub top_edge: VerticalFontMetric, - /// What line to consider the bottom edge of text. - pub bottom_edge: VerticalFontMetric, - /// The fill color of the text. - pub fill: Fill, - /// The specifications for a strikethrough line, if any. - pub strikethrough: Option, - /// The specifications for a underline, if any. - pub underline: Option, - /// The specifications for a overline line, if any. - pub overline: Option, + /// Color of the line. Will default to text color if `None`. + pub fill: Option, } /// Font family definitions. @@ -319,19 +242,3 @@ impl Display for FontFamily { }) } } - -/// Describes a line that could be positioned over or under text. -#[derive(Debug, Copy, Clone, PartialEq, Hash)] -pub struct LineProps { - /// Color of the line. - pub fill: Fill, - /// Thickness of the line's stroke. Calling functions should attempt to - /// read this value from the appropriate font tables if this is `None`. - pub strength: Option, - /// Position of the line relative to the baseline. Calling functions should - /// attempt to read this value from the appropriate font tables if this is - /// `None`. - pub position: Option, - /// Amount that the line will be longer or shorter than its associated text. - pub extent: Length, -} -- cgit v1.2.3