summaryrefslogtreecommitdiff
path: root/library/src/text
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-03-08 13:02:41 +0100
committerLaurenz <laurmaedje@gmail.com>2023-03-08 14:35:33 +0100
commitd7a65fa26d131179d9d82226e5ee1b562084e48a (patch)
treec21ab20e9fb851e14e1ebea3e14fc351b1fdbcc9 /library/src/text
parente5eab73374880077971f3f22acbdd3d302877128 (diff)
Rework style chain access
Diffstat (limited to 'library/src/text')
-rw-r--r--library/src/text/deco.rs51
-rw-r--r--library/src/text/misc.rs8
-rw-r--r--library/src/text/mod.rs13
-rw-r--r--library/src/text/raw.rs16
-rw-r--r--library/src/text/shaping.rs69
-rw-r--r--library/src/text/shift.rs18
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))