diff options
| author | Laurenz <laurmaedje@gmail.com> | 2022-04-07 10:50:39 +0200 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2022-04-07 11:07:00 +0200 |
| commit | 3d52387eea321e94c13b61666f7a758052b20c5d (patch) | |
| tree | 5c55c51ca7e4b53dee61d280c39b7f664b8b9d6b /src/library | |
| parent | 20b4d590b3efbd9b7a44fd6d3a658e7b84d21b99 (diff) | |
Rework style chains
Diffstat (limited to 'src/library')
| -rw-r--r-- | src/library/graphics/image.rs | 2 | ||||
| -rw-r--r-- | src/library/graphics/shape.rs | 2 | ||||
| -rw-r--r-- | src/library/layout/flow.rs | 4 | ||||
| -rw-r--r-- | src/library/layout/page.rs | 6 | ||||
| -rw-r--r-- | src/library/math/mod.rs | 11 | ||||
| -rw-r--r-- | src/library/prelude.rs | 4 | ||||
| -rw-r--r-- | src/library/structure/heading.rs | 42 | ||||
| -rw-r--r-- | src/library/structure/list.rs | 12 | ||||
| -rw-r--r-- | src/library/structure/table.rs | 7 | ||||
| -rw-r--r-- | src/library/text/deco.rs | 10 | ||||
| -rw-r--r-- | src/library/text/link.rs | 13 | ||||
| -rw-r--r-- | src/library/text/mod.rs | 162 | ||||
| -rw-r--r-- | src/library/text/par.rs | 9 | ||||
| -rw-r--r-- | src/library/text/raw.rs | 20 | ||||
| -rw-r--r-- | src/library/text/shaping.rs | 16 |
15 files changed, 188 insertions, 132 deletions
diff --git a/src/library/graphics/image.rs b/src/library/graphics/image.rs index d11de9d1..23ad52ab 100644 --- a/src/library/graphics/image.rs +++ b/src/library/graphics/image.rs @@ -82,7 +82,7 @@ impl Layout for ImageNode { } // Apply link if it exists. - if let Some(url) = styles.get_ref(TextNode::LINK) { + if let Some(url) = styles.get(TextNode::LINK) { frame.link(url); } diff --git a/src/library/graphics/shape.rs b/src/library/graphics/shape.rs index 9f9ff889..177f466e 100644 --- a/src/library/graphics/shape.rs +++ b/src/library/graphics/shape.rs @@ -132,7 +132,7 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> { } // Apply link if it exists. - if let Some(url) = styles.get_ref(TextNode::LINK) { + if let Some(url) = styles.get(TextNode::LINK) { frame.link(url); } diff --git a/src/library/layout/flow.rs b/src/library/layout/flow.rs index 3602bea6..9f398277 100644 --- a/src/library/layout/flow.rs +++ b/src/library/layout/flow.rs @@ -37,12 +37,12 @@ impl Layout for FlowNode { let styles = map.chain(&styles); match child { FlowChild::Leading => { - let em = styles.get(TextNode::SIZE).abs; + let em = styles.get(TextNode::SIZE); let amount = styles.get(ParNode::LEADING).resolve(em); layouter.layout_spacing(amount.into()); } FlowChild::Parbreak => { - let em = styles.get(TextNode::SIZE).abs; + let em = styles.get(TextNode::SIZE); let leading = styles.get(ParNode::LEADING); let spacing = styles.get(ParNode::SPACING); let amount = (leading + spacing).resolve(em); diff --git a/src/library/layout/page.rs b/src/library/layout/page.rs index b1008feb..c8af4843 100644 --- a/src/library/layout/page.rs +++ b/src/library/layout/page.rs @@ -28,8 +28,10 @@ impl PageNode { /// How many columns the page has. pub const COLUMNS: NonZeroUsize = NonZeroUsize::new(1).unwrap(); /// The page's header. + #[property(referenced)] pub const HEADER: Marginal = Marginal::None; /// The page's footer. + #[property(referenced)] pub const FOOTER: Marginal = Marginal::None; fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { @@ -116,8 +118,8 @@ impl PageNode { let regions = Regions::repeat(size, size, size.map(Length::is_finite)); let mut frames = child.layout(ctx, ®ions, styles)?; - let header = styles.get_ref(Self::HEADER); - let footer = styles.get_ref(Self::FOOTER); + let header = styles.get(Self::HEADER); + let footer = styles.get(Self::FOOTER); // Realize header and footer. for frame in &mut frames { diff --git a/src/library/math/mod.rs b/src/library/math/mod.rs index ddd80435..e6548438 100644 --- a/src/library/math/mod.rs +++ b/src/library/math/mod.rs @@ -15,6 +15,7 @@ pub struct MathNode { #[node(showable)] impl MathNode { /// The raw text's font family. Just the normal text family if `auto`. + #[property(referenced)] pub const FAMILY: Smart<FontFamily> = Smart::Custom(FontFamily::new("Latin Modern Math")); @@ -28,16 +29,14 @@ impl MathNode { impl Show for MathNode { fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { + let args = [Value::Str(self.formula.clone()), Value::Bool(self.display)]; let mut content = styles - .show(self, ctx, [ - Value::Str(self.formula.clone()), - Value::Bool(self.display), - ])? + .show::<Self, _>(ctx, args)? .unwrap_or_else(|| Content::Text(self.formula.trim().into())); let mut map = StyleMap::new(); - if let Smart::Custom(family) = styles.get_cloned(Self::FAMILY) { - map.set_family(family, styles); + if let Smart::Custom(family) = styles.get(Self::FAMILY) { + map.set_family(family.clone(), styles); } content = content.styled_with_map(map); diff --git a/src/library/prelude.rs b/src/library/prelude.rs index 39be5994..a2e296fa 100644 --- a/src/library/prelude.rs +++ b/src/library/prelude.rs @@ -9,8 +9,8 @@ pub use typst_macros::node; pub use crate::diag::{with_alternative, At, Error, StrResult, TypError, TypResult}; pub use crate::eval::{ - Arg, Args, Array, Cast, Content, Dict, Func, Key, Layout, LayoutNode, Merge, Node, - Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value, + Arg, Args, Array, Cast, Content, Dict, Fold, Func, Key, Layout, LayoutNode, Merge, + Node, Regions, Scope, Show, ShowNode, Smart, StyleChain, StyleMap, StyleVec, Value, }; pub use crate::frame::*; pub use crate::geom::*; diff --git a/src/library/structure/heading.rs b/src/library/structure/heading.rs index 7d3273f5..7b00c643 100644 --- a/src/library/structure/heading.rs +++ b/src/library/structure/heading.rs @@ -1,5 +1,5 @@ use crate::library::prelude::*; -use crate::library::text::{FontFamily, TextNode}; +use crate::library::text::{FontFamily, FontSize, TextNode, Toggle}; /// A section heading. #[derive(Debug, Hash)] @@ -14,25 +14,34 @@ pub struct HeadingNode { #[node(showable)] impl HeadingNode { /// The heading's font family. Just the normal text family if `auto`. + #[property(referenced)] pub const FAMILY: Leveled<Smart<FontFamily>> = Leveled::Value(Smart::Auto); /// The color of text in the heading. Just the normal text color if `auto`. + #[property(referenced)] pub const FILL: Leveled<Smart<Paint>> = Leveled::Value(Smart::Auto); /// The size of text in the heading. - pub const SIZE: Leveled<Linear> = Leveled::Mapping(|level| { + #[property(referenced)] + pub const SIZE: Leveled<FontSize> = Leveled::Mapping(|level| { let upscale = (1.6 - 0.1 * level as f64).max(0.75); - Relative::new(upscale).into() + FontSize(Relative::new(upscale).into()) }); /// Whether text in the heading is strengthend. + #[property(referenced)] pub const STRONG: Leveled<bool> = Leveled::Value(true); /// Whether text in the heading is emphasized. + #[property(referenced)] pub const EMPH: Leveled<bool> = Leveled::Value(false); /// Whether the heading is underlined. + #[property(referenced)] pub const UNDERLINE: Leveled<bool> = Leveled::Value(false); /// The extra padding above the heading. + #[property(referenced)] pub const ABOVE: Leveled<Length> = Leveled::Value(Length::zero()); /// The extra padding below the heading. + #[property(referenced)] pub const BELOW: Leveled<Length> = Leveled::Value(Length::zero()); /// Whether the heading is block-level. + #[property(referenced)] pub const BLOCK: Leveled<bool> = Leveled::Value(true); fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { @@ -47,16 +56,17 @@ impl Show for HeadingNode { fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { macro_rules! resolve { ($key:expr) => { - styles.get_cloned($key).resolve(ctx, self.level)? + styles.get($key).resolve(ctx, self.level)? }; } - // Resolve the user recipe. + let args = [ + Value::Int(self.level as i64), + Value::Content(self.body.clone()), + ]; + let mut body = styles - .show(self, ctx, [ - Value::Int(self.level as i64), - Value::Content(self.body.clone()), - ])? + .show::<Self, _>(ctx, args)? .unwrap_or_else(|| self.body.clone()); let mut map = StyleMap::new(); @@ -71,11 +81,11 @@ impl Show for HeadingNode { } if resolve!(Self::STRONG) { - map.set(TextNode::STRONG, true); + map.set(TextNode::STRONG, Toggle); } if resolve!(Self::EMPH) { - map.set(TextNode::EMPH, true); + map.set(TextNode::EMPH, Toggle); } let mut seq = vec![]; @@ -116,15 +126,15 @@ pub enum Leveled<T> { Func(Func, Span), } -impl<T: Cast> Leveled<T> { +impl<T: Cast + Clone> Leveled<T> { /// Resolve the value based on the level. - pub fn resolve(self, ctx: &mut Context, level: usize) -> TypResult<T> { + pub fn resolve(&self, ctx: &mut Context, level: usize) -> TypResult<T> { Ok(match self { - Self::Value(value) => value, + Self::Value(value) => value.clone(), Self::Mapping(mapping) => mapping(level), Self::Func(func, span) => { - let args = Args::from_values(span, [Value::Int(level as i64)]); - func.call(ctx, args)?.cast().at(span)? + let args = Args::from_values(*span, [Value::Int(level as i64)]); + func.call(ctx, args)?.cast().at(*span)? } }) } diff --git a/src/library/structure/list.rs b/src/library/structure/list.rs index 414f601e..1b22e166 100644 --- a/src/library/structure/list.rs +++ b/src/library/structure/list.rs @@ -31,6 +31,7 @@ pub type EnumNode = ListNode<ORDERED>; #[node(showable)] impl<const L: ListKind> ListNode<L> { /// How the list is labelled. + #[property(referenced)] pub const LABEL: Label = Label::Default; /// The spacing between the list items of a non-wide list. pub const SPACING: Linear = Linear::zero(); @@ -58,17 +59,14 @@ impl<const L: ListKind> ListNode<L> { impl<const L: ListKind> Show for ListNode<L> { fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { - let content = if let Some(content) = styles.show( - self, - ctx, - self.items.iter().map(|item| Value::Content((*item.body).clone())), - )? { + let args = self.items.iter().map(|item| Value::Content((*item.body).clone())); + let content = if let Some(content) = styles.show::<Self, _>(ctx, args)? { content } else { let mut children = vec![]; let mut number = self.start; - let label = styles.get_ref(Self::LABEL); + let label = styles.get(Self::LABEL); for item in &self.items { number = item.number.unwrap_or(number); @@ -79,7 +77,7 @@ impl<const L: ListKind> Show for ListNode<L> { number += 1; } - let em = styles.get(TextNode::SIZE).abs; + let em = styles.get(TextNode::SIZE); let leading = styles.get(ParNode::LEADING); let spacing = if self.wide { styles.get(ParNode::SPACING) diff --git a/src/library/structure/table.rs b/src/library/structure/table.rs index 0e455ead..64785006 100644 --- a/src/library/structure/table.rs +++ b/src/library/structure/table.rs @@ -55,11 +55,8 @@ impl TableNode { impl Show for TableNode { fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { - if let Some(content) = styles.show( - self, - ctx, - self.children.iter().map(|child| Value::Content(child.clone())), - )? { + let args = self.children.iter().map(|child| Value::Content(child.clone())); + if let Some(content) = styles.show::<Self, _>(ctx, args)? { return Ok(content); } diff --git a/src/library/text/deco.rs b/src/library/text/deco.rs index b98eb0b2..a6375e4e 100644 --- a/src/library/text/deco.rs +++ b/src/library/text/deco.rs @@ -21,11 +21,11 @@ pub type OverlineNode = DecoNode<OVERLINE>; #[node(showable)] impl<const L: DecoLine> DecoNode<L> { /// Stroke color of the line, defaults to the text color if `None`. - #[shorthand] + #[property(shorthand)] pub const STROKE: Option<Paint> = None; /// Thickness of the line's strokes (dependent on scaled font size), read /// from the font tables if `None`. - #[shorthand] + #[property(shorthand)] pub const THICKNESS: Option<Linear> = None; /// Position of the line relative to the baseline (dependent on scaled font /// size), read from the font tables if `None`. @@ -45,16 +45,16 @@ impl<const L: DecoLine> DecoNode<L> { impl<const L: DecoLine> Show for DecoNode<L> { fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { Ok(styles - .show(self, ctx, [Value::Content(self.0.clone())])? + .show::<Self, _>(ctx, [Value::Content(self.0.clone())])? .unwrap_or_else(|| { - self.0.clone().styled(TextNode::LINES, vec![Decoration { + self.0.clone().styled(TextNode::DECO, Decoration { line: L, stroke: styles.get(Self::STROKE), thickness: styles.get(Self::THICKNESS), offset: styles.get(Self::OFFSET), extent: styles.get(Self::EXTENT), evade: styles.get(Self::EVADE), - }]) + }) })) } } diff --git a/src/library/text/link.rs b/src/library/text/link.rs index 4c2b5e7b..3ef7011d 100644 --- a/src/library/text/link.rs +++ b/src/library/text/link.rs @@ -29,14 +29,13 @@ impl LinkNode { impl Show for LinkNode { fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { + let args = [Value::Str(self.url.clone()), match &self.body { + Some(body) => Value::Content(body.clone()), + None => Value::None, + }]; + let mut body = styles - .show(self, ctx, [ - Value::Str(self.url.clone()), - match &self.body { - Some(body) => Value::Content(body.clone()), - None => Value::None, - }, - ])? + .show::<Self, _>(ctx, args)? .or_else(|| self.body.clone()) .unwrap_or_else(|| { let url = &self.url; diff --git a/src/library/text/mod.rs b/src/library/text/mod.rs index 2c163a59..64994136 100644 --- a/src/library/text/mod.rs +++ b/src/library/text/mod.rs @@ -13,7 +13,6 @@ pub use raw::*; pub use shaping::*; use std::borrow::Cow; -use std::ops::BitXor; use ttf_parser::Tag; @@ -28,7 +27,7 @@ pub struct TextNode; #[node] impl TextNode { /// A prioritized sequence of font families. - #[variadic] + #[property(referenced, variadic)] pub const FAMILY: Vec<FontFamily> = vec![FontFamily::new("IBM Plex Sans")]; /// Whether to allow font fallback when the primary font list contains no /// match. @@ -40,14 +39,13 @@ impl TextNode { pub const WEIGHT: FontWeight = FontWeight::REGULAR; /// The width of the glyphs. pub const STRETCH: FontStretch = FontStretch::NORMAL; + /// The size of the glyphs. + #[property(shorthand, fold)] + pub const SIZE: FontSize = Length::pt(11.0); /// The glyph fill color. - #[shorthand] + #[property(shorthand)] pub const FILL: Paint = Color::BLACK.into(); - /// The size of the glyphs. - #[shorthand] - #[fold(Linear::compose)] - pub const SIZE: Linear = Length::pt(11.0).into(); /// The amount of space that should be added between characters. pub const TRACKING: Em = Em::zero(); /// The ratio by which spaces should be stretched. @@ -84,26 +82,24 @@ impl TextNode { /// Whether to convert fractions. ("frac") pub const FRACTIONS: bool = false; /// Raw OpenType features to apply. + #[property(fold)] pub const FEATURES: Vec<(Tag, u32)> = vec![]; /// Whether the font weight should be increased by 300. - #[skip] - #[fold(bool::bitxor)] - pub const STRONG: bool = false; + #[property(hidden, fold)] + pub const STRONG: Toggle = false; /// Whether the the font style should be inverted. - #[skip] - #[fold(bool::bitxor)] - pub const EMPH: bool = false; - /// The case transformation that should be applied to the next. - #[skip] + #[property(hidden, fold)] + pub const EMPH: Toggle = false; + /// A case transformation that should be applied to the text. + #[property(hidden)] pub const CASE: Option<Case> = None; - /// Decorative lines. - #[skip] - #[fold(|a, b| a.into_iter().chain(b).collect())] - pub const LINES: Vec<Decoration> = vec![]; /// An URL the text should link to. - #[skip] + #[property(hidden, referenced)] pub const LINK: Option<EcoString> = None; + /// Decorative lines. + #[property(hidden, fold)] + pub const DECO: Decoration = vec![]; fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { // The text constructor is special: It doesn't create a text node. @@ -113,44 +109,6 @@ impl TextNode { } } -/// Strong text, rendered in boldface. -#[derive(Debug, Hash)] -pub struct StrongNode(pub Content); - -#[node(showable)] -impl StrongNode { - fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { - Ok(Content::show(Self(args.expect("body")?))) - } -} - -impl Show for StrongNode { - fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { - Ok(styles - .show(self, ctx, [Value::Content(self.0.clone())])? - .unwrap_or_else(|| self.0.clone().styled(TextNode::STRONG, true))) - } -} - -/// Emphasized text, rendered with an italic face. -#[derive(Debug, Hash)] -pub struct EmphNode(pub Content); - -#[node(showable)] -impl EmphNode { - fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { - Ok(Content::show(Self(args.expect("body")?))) - } -} - -impl Show for EmphNode { - fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { - Ok(styles - .show(self, ctx, [Value::Content(self.0.clone())])? - .unwrap_or_else(|| self.0.clone().styled(TextNode::EMPH, true))) - } -} - /// A font family like "Arial". #[derive(Clone, Eq, PartialEq, Hash)] pub struct FontFamily(EcoString); @@ -228,6 +186,26 @@ castable! { Value::Relative(v) => Self::from_ratio(v.get() as f32), } +/// The size of text. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct FontSize(pub Linear); + +impl Fold for FontSize { + type Output = Length; + + fn fold(self, outer: Self::Output) -> Self::Output { + self.0.rel.resolve(outer) + self.0.abs + } +} + +castable! { + FontSize, + Expected: "linear", + Value::Length(v) => Self(v.into()), + Value::Relative(v) => Self(v.into()), + Value::Linear(v) => Self(v), +} + castable! { Em, Expected: "float", @@ -353,6 +331,15 @@ castable! { .collect(), } +impl Fold for Vec<(Tag, u32)> { + type Output = Self; + + fn fold(mut self, outer: Self::Output) -> Self::Output { + self.extend(outer); + self + } +} + /// A case transformation on text. #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum Case { @@ -371,3 +358,62 @@ impl Case { } } } + +/// A toggle that turns on and off alternatingly if folded. +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub struct Toggle; + +impl Fold for Toggle { + type Output = bool; + + fn fold(self, outer: Self::Output) -> Self::Output { + !outer + } +} + +impl Fold for Decoration { + type Output = Vec<Self>; + + fn fold(self, mut outer: Self::Output) -> Self::Output { + outer.insert(0, self); + outer + } +} + +/// Strong text, rendered in boldface. +#[derive(Debug, Hash)] +pub struct StrongNode(pub Content); + +#[node(showable)] +impl StrongNode { + fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { + Ok(Content::show(Self(args.expect("body")?))) + } +} + +impl Show for StrongNode { + fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { + Ok(styles + .show::<Self, _>(ctx, [Value::Content(self.0.clone())])? + .unwrap_or_else(|| self.0.clone().styled(TextNode::STRONG, Toggle))) + } +} + +/// Emphasized text, rendered with an italic face. +#[derive(Debug, Hash)] +pub struct EmphNode(pub Content); + +#[node(showable)] +impl EmphNode { + fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { + Ok(Content::show(Self(args.expect("body")?))) + } +} + +impl Show for EmphNode { + fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { + Ok(styles + .show::<Self, _>(ctx, [Value::Content(self.0.clone())])? + .unwrap_or_else(|| self.0.clone().styled(TextNode::EMPH, Toggle))) + } +} diff --git a/src/library/text/par.rs b/src/library/text/par.rs index 97e5a3f5..67357135 100644 --- a/src/library/text/par.rs +++ b/src/library/text/par.rs @@ -28,6 +28,7 @@ pub enum ParChild { #[node] impl ParNode { /// An ISO 639-1 language code. + #[property(referenced)] pub const LANG: Option<EcoString> = None; /// The direction for text and inline objects. pub const DIR: Dir = Dir::LTR; @@ -611,7 +612,7 @@ fn breakpoints<'a>( let mut lang = None; if styles.get(ParNode::HYPHENATE).unwrap_or(styles.get(ParNode::JUSTIFY)) { lang = styles - .get_ref(ParNode::LANG) + .get(ParNode::LANG) .as_ref() .and_then(|iso| iso.as_bytes().try_into().ok()) .and_then(hypher::Lang::from_iso); @@ -768,7 +769,7 @@ fn stack( regions: &Regions, styles: StyleChain, ) -> Vec<Arc<Frame>> { - let em = styles.get(TextNode::SIZE).abs; + let em = styles.get(TextNode::SIZE); let leading = styles.get(ParNode::LEADING).resolve(em); let align = styles.get(ParNode::ALIGN); let justify = styles.get(ParNode::JUSTIFY); @@ -832,7 +833,7 @@ fn commit( if let Some(glyph) = text.glyphs.first() { if text.styles.get(TextNode::OVERHANG) { let start = text.dir.is_positive(); - let em = text.styles.get(TextNode::SIZE).abs; + let em = text.styles.get(TextNode::SIZE); let amount = overhang(glyph.c, start) * glyph.x_advance.resolve(em); offset -= amount; remaining += amount; @@ -847,7 +848,7 @@ fn commit( && (reordered.len() > 1 || text.glyphs.len() > 1) { let start = !text.dir.is_positive(); - let em = text.styles.get(TextNode::SIZE).abs; + let em = text.styles.get(TextNode::SIZE); let amount = overhang(glyph.c, start) * glyph.x_advance.resolve(em); remaining += amount; } diff --git a/src/library/text/raw.rs b/src/library/text/raw.rs index 5c2133c2..f09bc1d0 100644 --- a/src/library/text/raw.rs +++ b/src/library/text/raw.rs @@ -3,7 +3,7 @@ use syntect::easy::HighlightLines; use syntect::highlighting::{FontStyle, Highlighter, Style, Theme, ThemeSet}; use syntect::parsing::SyntaxSet; -use super::{FontFamily, TextNode}; +use super::{FontFamily, TextNode, Toggle}; use crate::library::prelude::*; use crate::source::SourceId; use crate::syntax::{self, RedNode}; @@ -27,8 +27,10 @@ pub struct RawNode { #[node(showable)] impl RawNode { /// The raw text's font family. Just the normal text family if `none`. + #[property(referenced)] pub const FAMILY: Smart<FontFamily> = Smart::Custom(FontFamily::new("IBM Plex Mono")); /// The language to syntax-highlight in. + #[property(referenced)] pub const LANG: Option<EcoString> = None; fn construct(_: &mut Context, args: &mut Args) -> TypResult<Content> { @@ -41,7 +43,7 @@ impl RawNode { impl Show for RawNode { fn show(&self, ctx: &mut Context, styles: StyleChain) -> TypResult<Content> { - let lang = styles.get_ref(Self::LANG).as_ref(); + let lang = styles.get(Self::LANG).as_ref(); let foreground = THEME .settings .foreground @@ -49,14 +51,16 @@ impl Show for RawNode { .unwrap_or(Color::BLACK) .into(); - let mut content = if let Some(content) = styles.show(self, ctx, [ + let args = [ Value::Str(self.text.clone()), match lang { Some(lang) => Value::Str(lang.clone()), None => Value::None, }, Value::Bool(self.block), - ])? { + ]; + + let mut content = if let Some(content) = styles.show::<Self, _>(ctx, args)? { content } else if matches!( lang.map(|s| s.to_lowercase()).as_deref(), @@ -93,8 +97,8 @@ impl Show for RawNode { }; let mut map = StyleMap::new(); - if let Smart::Custom(family) = styles.get_cloned(Self::FAMILY) { - map.set_family(family, styles); + if let Smart::Custom(family) = styles.get(Self::FAMILY) { + map.set_family(family.clone(), styles); } content = content.styled_with_map(map); @@ -118,11 +122,11 @@ fn styled(piece: &str, foreground: Paint, style: Style) -> Content { } if style.font_style.contains(FontStyle::BOLD) { - styles.set(TextNode::STRONG, true); + styles.set(TextNode::STRONG, Toggle); } if style.font_style.contains(FontStyle::ITALIC) { - styles.set(TextNode::EMPH, true); + styles.set(TextNode::EMPH, Toggle); } if style.font_style.contains(FontStyle::UNDERLINE) { diff --git a/src/library/text/shaping.rs b/src/library/text/shaping.rs index 6087032f..66936792 100644 --- a/src/library/text/shaping.rs +++ b/src/library/text/shaping.rs @@ -77,7 +77,7 @@ impl<'a> ShapedText<'a> { for (face_id, group) in self.glyphs.as_ref().group_by_key(|g| g.face_id) { let pos = Point::new(offset, self.baseline); - let size = self.styles.get(TextNode::SIZE).abs; + let size = self.styles.get(TextNode::SIZE); let fill = self.styles.get(TextNode::FILL); let glyphs = group .iter() @@ -99,7 +99,7 @@ impl<'a> ShapedText<'a> { let width = text.width(); // Apply line decorations. - for deco in self.styles.get_cloned(TextNode::LINES) { + for deco in self.styles.get(TextNode::DECO) { decorate(&mut frame, &deco, fonts, &text, pos, width); } @@ -108,7 +108,7 @@ impl<'a> ShapedText<'a> { } // Apply link if it exists. - if let Some(url) = self.styles.get_ref(TextNode::LINK) { + if let Some(url) = self.styles.get(TextNode::LINK) { frame.link(url); } @@ -127,7 +127,7 @@ impl<'a> ShapedText<'a> { .filter(|g| g.is_space()) .map(|g| g.x_advance) .sum::<Em>() - .resolve(self.styles.get(TextNode::SIZE).abs) + .resolve(self.styles.get(TextNode::SIZE)) } /// Reshape a range of the shaped text, reusing information from this @@ -154,7 +154,7 @@ impl<'a> ShapedText<'a> { /// Push a hyphen to end of the text. pub fn push_hyphen(&mut self, fonts: &mut FontStore) { - let size = self.styles.get(TextNode::SIZE).abs; + let size = self.styles.get(TextNode::SIZE); let variant = variant(self.styles); families(self.styles).find_map(|family| { let face_id = fonts.select(family, variant)?; @@ -467,7 +467,7 @@ fn measure( let mut top = Length::zero(); let mut bottom = Length::zero(); - let size = styles.get(TextNode::SIZE).abs; + let size = styles.get(TextNode::SIZE); let top_edge = styles.get(TextNode::TOP_EDGE); let bottom_edge = styles.get(TextNode::BOTTOM_EDGE); @@ -537,7 +537,7 @@ fn families(styles: StyleChain) -> impl Iterator<Item = &str> + Clone { let tail = if styles.get(TextNode::FALLBACK) { FALLBACKS } else { &[] }; styles - .get_ref(TextNode::FAMILY) + .get(TextNode::FAMILY) .iter() .map(|family| family.as_str()) .chain(tail.iter().copied()) @@ -609,7 +609,7 @@ fn tags(styles: StyleChain) -> Vec<Feature> { feat(b"frac", 1); } - for &(tag, value) in styles.get_ref(TextNode::FEATURES).iter() { + for (tag, value) in styles.get(TextNode::FEATURES) { tags.push(Feature::new(tag, value, ..)) } |
