diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-08 13:02:41 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-08 14:35:33 +0100 |
| commit | d7a65fa26d131179d9d82226e5ee1b562084e48a (patch) | |
| tree | c21ab20e9fb851e14e1ebea3e14fc351b1fdbcc9 /library/src/text | |
| parent | e5eab73374880077971f3f22acbdd3d302877128 (diff) | |
Rework style chain access
Diffstat (limited to 'library/src/text')
| -rw-r--r-- | library/src/text/deco.rs | 51 | ||||
| -rw-r--r-- | library/src/text/misc.rs | 8 | ||||
| -rw-r--r-- | library/src/text/mod.rs | 13 | ||||
| -rw-r--r-- | library/src/text/raw.rs | 16 | ||||
| -rw-r--r-- | library/src/text/shaping.rs | 69 | ||||
| -rw-r--r-- | library/src/text/shift.rs | 18 |
6 files changed, 83 insertions, 92 deletions
diff --git a/library/src/text/deco.rs b/library/src/text/deco.rs index d47b336b..1b3167e1 100644 --- a/library/src/text/deco.rs +++ b/library/src/text/deco.rs @@ -75,16 +75,13 @@ pub struct UnderlineNode { impl Show for UnderlineNode { fn show(&self, _: &mut Vt, _: &Content, styles: StyleChain) -> SourceResult<Content> { - Ok(self.body().styled( - TextNode::DECO, - Decoration { - line: DecoLine::Underline, - stroke: styles.get(Self::STROKE).unwrap_or_default(), - offset: styles.get(Self::OFFSET), - extent: styles.get(Self::EXTENT), - evade: styles.get(Self::EVADE), - }, - )) + Ok(self.body().styled(TextNode::set_deco(Decoration { + line: DecoLine::Underline, + stroke: Self::stroke_in(styles).unwrap_or_default(), + offset: Self::offset_in(styles), + extent: Self::extent_in(styles), + evade: Self::evade_in(styles), + }))) } } @@ -165,16 +162,13 @@ pub struct OverlineNode { impl Show for OverlineNode { fn show(&self, _: &mut Vt, _: &Content, styles: StyleChain) -> SourceResult<Content> { - Ok(self.body().styled( - TextNode::DECO, - Decoration { - line: DecoLine::Overline, - stroke: styles.get(Self::STROKE).unwrap_or_default(), - offset: styles.get(Self::OFFSET), - extent: styles.get(Self::EXTENT), - evade: styles.get(Self::EVADE), - }, - )) + Ok(self.body().styled(TextNode::set_deco(Decoration { + line: DecoLine::Overline, + stroke: Self::stroke_in(styles).unwrap_or_default(), + offset: Self::offset_in(styles), + extent: Self::extent_in(styles), + evade: Self::evade_in(styles), + }))) } } @@ -239,16 +233,13 @@ pub struct StrikeNode { impl Show for StrikeNode { fn show(&self, _: &mut Vt, _: &Content, styles: StyleChain) -> SourceResult<Content> { - Ok(self.body().styled( - TextNode::DECO, - Decoration { - line: DecoLine::Strikethrough, - stroke: styles.get(Self::STROKE).unwrap_or_default(), - offset: styles.get(Self::OFFSET), - extent: styles.get(Self::EXTENT), - evade: false, - }, - )) + Ok(self.body().styled(TextNode::set_deco(Decoration { + line: DecoLine::Strikethrough, + stroke: Self::stroke_in(styles).unwrap_or_default(), + offset: Self::offset_in(styles), + extent: Self::extent_in(styles), + evade: false, + }))) } } diff --git a/library/src/text/misc.rs b/library/src/text/misc.rs index 9caaf68e..91ac1748 100644 --- a/library/src/text/misc.rs +++ b/library/src/text/misc.rs @@ -103,7 +103,7 @@ pub struct StrongNode { impl Show for StrongNode { fn show(&self, _: &mut Vt, _: &Content, styles: StyleChain) -> SourceResult<Content> { - Ok(self.body().styled(TextNode::DELTA, Delta(styles.get(Self::DELTA)))) + Ok(self.body().styled(TextNode::set_delta(Delta(Self::delta_in(styles))))) } } @@ -164,7 +164,7 @@ pub struct EmphNode { impl Show for EmphNode { fn show(&self, _: &mut Vt, _: &Content, _: StyleChain) -> SourceResult<Content> { - Ok(self.body().styled(TextNode::EMPH, Toggle)) + Ok(self.body().styled(TextNode::set_emph(Toggle))) } } @@ -233,7 +233,7 @@ pub fn upper(args: &mut Args) -> SourceResult<Value> { fn case(case: Case, args: &mut Args) -> SourceResult<Value> { Ok(match args.expect("string or content")? { ToCase::Str(v) => Value::Str(case.apply(&v).into()), - ToCase::Content(v) => Value::Content(v.styled(TextNode::CASE, Some(case))), + ToCase::Content(v) => Value::Content(v.styled(TextNode::set_case(Some(case)))), }) } @@ -313,7 +313,7 @@ cast_to_value! { #[func] pub fn smallcaps(args: &mut Args) -> SourceResult<Value> { let body: Content = args.expect("content")?; - Ok(Value::Content(body.styled(TextNode::SMALLCAPS, true))) + Ok(Value::Content(body.styled(TextNode::set_smallcaps(true)))) } /// Create blind text. diff --git a/library/src/text/mod.rs b/library/src/text/mod.rs index 329ff6a9..2318c426 100644 --- a/library/src/text/mod.rs +++ b/library/src/text/mod.rs @@ -578,6 +578,15 @@ cast_to_value! { #[derive(Debug, Default, Clone, Eq, PartialEq, Hash)] pub struct FontList(pub Vec<FontFamily>); +impl IntoIterator for FontList { + type IntoIter = std::vec::IntoIter<FontFamily>; + type Item = FontFamily; + + fn into_iter(self) -> Self::IntoIter { + self.0.into_iter() + } +} + cast_from_value! { FontList, family: FontFamily => Self(vec![family]), @@ -664,7 +673,7 @@ impl Resolve for HorizontalDir { fn resolve(self, styles: StyleChain) -> Self::Output { match self.0 { - Smart::Auto => styles.get(TextNode::LANG).dir(), + Smart::Auto => TextNode::lang_in(styles).dir(), Smart::Custom(dir) => dir, } } @@ -688,7 +697,7 @@ impl Resolve for Hyphenate { fn resolve(self, styles: StyleChain) -> Self::Output { match self.0 { - Smart::Auto => styles.get(ParNode::JUSTIFY), + Smart::Auto => ParNode::justify_in(styles), Smart::Custom(v) => v, } } diff --git a/library/src/text/raw.rs b/library/src/text/raw.rs index 4eefb0ea..8526a278 100644 --- a/library/src/text/raw.rs +++ b/library/src/text/raw.rs @@ -114,7 +114,7 @@ impl Prepare for RawNode { mut this: Content, styles: StyleChain, ) -> SourceResult<Content> { - this.push_field("lang", styles.get(Self::LANG).clone()); + this.push_field("lang", Self::lang_in(styles).clone()); Ok(this) } } @@ -122,7 +122,7 @@ impl Prepare for RawNode { impl Show for RawNode { fn show(&self, _: &mut Vt, _: &Content, styles: StyleChain) -> SourceResult<Content> { let text = self.text(); - let lang = styles.get(Self::LANG).as_ref().map(|s| s.to_lowercase()); + let lang = Self::lang_in(styles).as_ref().map(|s| s.to_lowercase()); let foreground = THEME .settings .foreground @@ -181,11 +181,11 @@ impl Show for RawNode { impl Finalize for RawNode { fn finalize(&self, realized: Content) -> Content { let mut map = StyleMap::new(); - map.set(TextNode::OVERHANG, false); - map.set(TextNode::HYPHENATE, Hyphenate(Smart::Custom(false))); - map.set(TextNode::SIZE, TextSize(Em::new(0.8).into())); - map.set(TextNode::FONT, FontList(vec![FontFamily::new("DejaVu Sans Mono")])); - map.set(SmartQuoteNode::ENABLED, false); + map.set(TextNode::set_overhang(false)); + map.set(TextNode::set_hyphenate(Hyphenate(Smart::Custom(false)))); + map.set(TextNode::set_size(TextSize(Em::new(0.8).into()))); + map.set(TextNode::set_font(FontList(vec![FontFamily::new("DejaVu Sans Mono")]))); + map.set(SmartQuoteNode::set_enabled(false)); realized.styled_with_map(map) } } @@ -221,7 +221,7 @@ fn styled(piece: &str, foreground: Paint, style: synt::Style) -> Content { let paint = to_typst(style.foreground).into(); if paint != foreground { - body = body.styled(TextNode::FILL, paint); + body = body.styled(TextNode::set_fill(paint)); } if style.font_style.contains(synt::FontStyle::BOLD) { diff --git a/library/src/text/shaping.rs b/library/src/text/shaping.rs index e1b12120..e7ce4027 100644 --- a/library/src/text/shaping.rs +++ b/library/src/text/shaping.rs @@ -88,10 +88,10 @@ impl<'a> ShapedText<'a> { let mut frame = Frame::new(size); frame.set_baseline(top); - let shift = self.styles.get(TextNode::BASELINE); - let lang = self.styles.get(TextNode::LANG); - let decos = self.styles.get(TextNode::DECO); - let fill = self.styles.get(TextNode::FILL); + let shift = TextNode::baseline_in(self.styles); + let lang = TextNode::lang_in(self.styles); + let decos = TextNode::deco_in(self.styles); + let fill = TextNode::fill_in(self.styles); for ((font, y_offset), group) in self.glyphs.as_ref().group_by_key(|g| (g.font.clone(), g.y_offset)) @@ -137,8 +137,8 @@ impl<'a> ShapedText<'a> { let mut top = Abs::zero(); let mut bottom = Abs::zero(); - let top_edge = self.styles.get(TextNode::TOP_EDGE); - let bottom_edge = self.styles.get(TextNode::BOTTOM_EDGE); + let top_edge = TextNode::top_edge_in(self.styles); + let bottom_edge = TextNode::bottom_edge_in(self.styles); // Expand top and bottom by reading the font's vertical metrics. let mut expand = |font: &Font| { @@ -315,8 +315,7 @@ pub fn shape<'a>( styles: StyleChain<'a>, dir: Dir, ) -> ShapedText<'a> { - let size = styles.get(TextNode::SIZE); - + let size = TextNode::size_in(styles); let mut ctx = ShapingContext { vt, size, @@ -325,7 +324,7 @@ pub fn shape<'a>( styles, variant: variant(styles), tags: tags(styles), - fallback: styles.get(TextNode::FALLBACK), + fallback: TextNode::fallback_in(styles), dir, }; @@ -494,11 +493,9 @@ fn shape_tofus(ctx: &mut ShapingContext, base: usize, text: &str, font: Font) { /// Apply tracking and spacing to the shaped glyphs. fn track_and_space(ctx: &mut ShapingContext) { - let tracking = Em::from_length(ctx.styles.get(TextNode::TRACKING), ctx.size); - let spacing = ctx - .styles - .get(TextNode::SPACING) - .map(|abs| Em::from_length(abs, ctx.size)); + let tracking = Em::from_length(TextNode::tracking_in(ctx.styles), ctx.size); + let spacing = + TextNode::spacing_in(ctx.styles).map(|abs| Em::from_length(abs, ctx.size)); let mut glyphs = ctx.glyphs.iter_mut().peekable(); while let Some(glyph) = glyphs.next() { @@ -527,17 +524,17 @@ fn nbsp_delta(font: &Font) -> Option<Em> { /// Resolve the font variant. pub fn variant(styles: StyleChain) -> FontVariant { let mut variant = FontVariant::new( - styles.get(TextNode::STYLE), - styles.get(TextNode::WEIGHT), - styles.get(TextNode::STRETCH), + TextNode::style_in(styles), + TextNode::weight_in(styles), + TextNode::stretch_in(styles), ); - let delta = styles.get(TextNode::DELTA); + let delta = TextNode::delta_in(styles); variant.weight = variant .weight .thicken(delta.clamp(i16::MIN as i64, i16::MAX as i64) as i16); - if styles.get(TextNode::EMPH) { + if TextNode::emph_in(styles) { variant.style = match variant.style { FontStyle::Normal => FontStyle::Italic, FontStyle::Italic => FontStyle::Normal, @@ -558,10 +555,8 @@ pub fn families(styles: StyleChain) -> impl Iterator<Item = FontFamily> + Clone "segoe ui emoji", ]; - let tail = if styles.get(TextNode::FALLBACK) { FALLBACKS } else { &[] }; - styles - .get(TextNode::FONT) - .0 + let tail = if TextNode::fallback_in(styles) { FALLBACKS } else { &[] }; + TextNode::font_in(styles) .into_iter() .chain(tail.iter().copied().map(FontFamily::new)) } @@ -574,59 +569,59 @@ fn tags(styles: StyleChain) -> Vec<Feature> { }; // Features that are on by default in Harfbuzz are only added if disabled. - if !styles.get(TextNode::KERNING) { + if !TextNode::kerning_in(styles) { feat(b"kern", 0); } // Features that are off by default in Harfbuzz are only added if enabled. - if styles.get(TextNode::SMALLCAPS) { + if TextNode::smallcaps_in(styles) { feat(b"smcp", 1); } - if styles.get(TextNode::ALTERNATES) { + if TextNode::alternates_in(styles) { feat(b"salt", 1); } let storage; - if let Some(set) = styles.get(TextNode::STYLISTIC_SET) { + if let Some(set) = TextNode::stylistic_set_in(styles) { storage = [b's', b's', b'0' + set.get() / 10, b'0' + set.get() % 10]; feat(&storage, 1); } - if !styles.get(TextNode::LIGATURES) { + if !TextNode::ligatures_in(styles) { feat(b"liga", 0); feat(b"clig", 0); } - if styles.get(TextNode::DISCRETIONARY_LIGATURES) { + if TextNode::discretionary_ligatures_in(styles) { feat(b"dlig", 1); } - if styles.get(TextNode::HISTORICAL_LIGATURES) { + if TextNode::historical_ligatures_in(styles) { feat(b"hilg", 1); } - match styles.get(TextNode::NUMBER_TYPE) { + match TextNode::number_type_in(styles) { Smart::Auto => {} Smart::Custom(NumberType::Lining) => feat(b"lnum", 1), Smart::Custom(NumberType::OldStyle) => feat(b"onum", 1), } - match styles.get(TextNode::NUMBER_WIDTH) { + match TextNode::number_width_in(styles) { Smart::Auto => {} Smart::Custom(NumberWidth::Proportional) => feat(b"pnum", 1), Smart::Custom(NumberWidth::Tabular) => feat(b"tnum", 1), } - if styles.get(TextNode::SLASHED_ZERO) { + if TextNode::slashed_zero_in(styles) { feat(b"zero", 1); } - if styles.get(TextNode::FRACTIONS) { + if TextNode::fractions_in(styles) { feat(b"frac", 1); } - for (tag, value) in styles.get(TextNode::FEATURES).0 { + for (tag, value) in TextNode::features_in(styles).0 { tags.push(Feature::new(tag, value, ..)) } @@ -636,8 +631,8 @@ fn tags(styles: StyleChain) -> Vec<Feature> { /// Process the language and and region of a style chain into a /// rustybuzz-compatible BCP 47 language. fn language(styles: StyleChain) -> rustybuzz::Language { - let mut bcp: EcoString = styles.get(TextNode::LANG).as_str().into(); - if let Some(region) = styles.get(TextNode::REGION) { + let mut bcp: EcoString = TextNode::lang_in(styles).as_str().into(); + if let Some(region) = TextNode::region_in(styles) { bcp.push('-'); bcp.push_str(region.as_str()); } diff --git a/library/src/text/shift.rs b/library/src/text/shift.rs index c44cc3b0..98718365 100644 --- a/library/src/text/shift.rs +++ b/library/src/text/shift.rs @@ -59,7 +59,7 @@ impl Show for SubNode { ) -> SourceResult<Content> { let body = self.body(); let mut transformed = None; - if styles.get(Self::TYPOGRAPHIC) { + if Self::typographic_in(styles) { if let Some(text) = search_text(&body, true) { if is_shapable(vt, &text, styles) { transformed = Some(TextNode::packed(text)); @@ -68,10 +68,8 @@ impl Show for SubNode { }; Ok(transformed.unwrap_or_else(|| { - let mut map = StyleMap::new(); - map.set(TextNode::BASELINE, styles.get(Self::BASELINE)); - map.set(TextNode::SIZE, styles.get(Self::SIZE)); - body.styled_with_map(map) + body.styled(TextNode::set_baseline(Self::baseline_in(styles))) + .styled(TextNode::set_size(Self::size_in(styles))) })) } } @@ -132,7 +130,7 @@ impl Show for SuperNode { ) -> SourceResult<Content> { let body = self.body(); let mut transformed = None; - if styles.get(Self::TYPOGRAPHIC) { + if Self::typographic_in(styles) { if let Some(text) = search_text(&body, false) { if is_shapable(vt, &text, styles) { transformed = Some(TextNode::packed(text)); @@ -141,10 +139,8 @@ impl Show for SuperNode { }; Ok(transformed.unwrap_or_else(|| { - let mut map = StyleMap::new(); - map.set(TextNode::BASELINE, styles.get(Self::BASELINE)); - map.set(TextNode::SIZE, styles.get(Self::SIZE)); - body.styled_with_map(map) + body.styled(TextNode::set_baseline(Self::baseline_in(styles))) + .styled(TextNode::set_size(Self::size_in(styles))) })) } } @@ -174,7 +170,7 @@ fn search_text(content: &Content, sub: bool) -> Option<EcoString> { /// given string. fn is_shapable(vt: &Vt, text: &str, styles: StyleChain) -> bool { let world = vt.world(); - for family in styles.get(TextNode::FONT).0.iter() { + for family in TextNode::font_in(styles) { if let Some(font) = world .book() .select(family.as_str(), variant(styles)) |
