summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-29 14:57:05 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-29 14:57:05 +0100
commit579dac3c91faf73866f4b9b13381393ddf7b2f9b (patch)
treee490708005997ba4db1d98ee1a2cac6c6d669c83
parent0efe669278a5e1c3f2985eba2f3360e91159c54a (diff)
Strong delta
-rw-r--r--library/src/text/misc.rs31
-rw-r--r--library/src/text/mod.rs6
-rw-r--r--library/src/text/shaping.rs9
-rw-r--r--src/model/cast.rs5
-rw-r--r--tests/fonts/IBMPlexSans-Medium.ttfbin0 -> 177104 bytes
-rw-r--r--tests/ref/text/emphasis.pngbin6900 -> 8898 bytes
-rw-r--r--tests/typ/text/emphasis.typ10
7 files changed, 45 insertions, 16 deletions
diff --git a/library/src/text/misc.rs b/library/src/text/misc.rs
index 15ef9a63..32e0cc1d 100644
--- a/library/src/text/misc.rs
+++ b/library/src/text/misc.rs
@@ -40,12 +40,15 @@ impl Behave for LinebreakNode {
}
}
-/// Strong content, rendered in boldface by default.
+/// Strongly emphasizes content by increasing the font weight.
#[derive(Debug, Hash)]
pub struct StrongNode(pub Content);
#[node(Show)]
impl StrongNode {
+ /// The delta to apply on the font weight.
+ pub const DELTA: i64 = 300;
+
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
}
@@ -59,12 +62,30 @@ impl StrongNode {
}
impl Show for StrongNode {
- fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> Content {
- self.0.clone().styled(TextNode::BOLD, Toggle)
+ fn show(&self, _: Tracked<dyn World>, styles: StyleChain) -> Content {
+ self.0.clone().styled(TextNode::DELTA, Delta(styles.get(Self::DELTA)))
+ }
+}
+
+/// A delta that is summed up when folded.
+#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct Delta(pub i64);
+
+castable! {
+ Delta,
+ Expected: "integer",
+ Value::Int(delta) => Self(delta),
+}
+
+impl Fold for Delta {
+ type Output = i64;
+
+ fn fold(self, outer: Self::Output) -> Self::Output {
+ outer + self.0
}
}
-/// Emphasized content, rendered with an italic font by default.
+/// Emphasizes content by flipping the italicness.
#[derive(Debug, Hash)]
pub struct EmphNode(pub Content);
@@ -84,7 +105,7 @@ impl EmphNode {
impl Show for EmphNode {
fn show(&self, _: Tracked<dyn World>, _: StyleChain) -> Content {
- self.0.clone().styled(TextNode::ITALIC, Toggle)
+ self.0.clone().styled(TextNode::EMPH, Toggle)
}
}
diff --git a/library/src/text/mod.rs b/library/src/text/mod.rs
index c9298fee..47aaba36 100644
--- a/library/src/text/mod.rs
+++ b/library/src/text/mod.rs
@@ -111,12 +111,12 @@ impl TextNode {
#[property(fold)]
pub const FEATURES: FontFeatures = FontFeatures(vec![]);
- /// Whether the font weight should be increased by 300.
+ /// A delta to apply on the font weight.
#[property(skip, fold)]
- pub const BOLD: Toggle = false;
+ pub const DELTA: Delta = 0;
/// Whether the font style should be inverted.
#[property(skip, fold)]
- pub const ITALIC: Toggle = false;
+ pub const EMPH: Toggle = false;
/// A case transformation that should be applied to the text.
#[property(skip)]
pub const CASE: Option<Case> = None;
diff --git a/library/src/text/shaping.rs b/library/src/text/shaping.rs
index 687f2a87..88fec39d 100644
--- a/library/src/text/shaping.rs
+++ b/library/src/text/shaping.rs
@@ -537,11 +537,12 @@ pub fn variant(styles: StyleChain) -> FontVariant {
styles.get(TextNode::STRETCH),
);
- if styles.get(TextNode::BOLD) {
- variant.weight = variant.weight.thicken(300);
- }
+ let delta = styles.get(TextNode::DELTA);
+ variant.weight = variant
+ .weight
+ .thicken(delta.clamp(i16::MIN as i64, i16::MAX as i64) as i16);
- if styles.get(TextNode::ITALIC) {
+ if styles.get(TextNode::EMPH) {
variant.style = match variant.style {
FontStyle::Normal => FontStyle::Italic,
FontStyle::Italic => FontStyle::Normal,
diff --git a/src/model/cast.rs b/src/model/cast.rs
index df3c8c81..6a78eebd 100644
--- a/src/model/cast.rs
+++ b/src/model/cast.rs
@@ -280,10 +280,7 @@ castable! {
castable! {
FontWeight,
Expected: "integer or string",
- Value::Int(v) => Value::Int(v)
- .cast::<usize>()?
- .try_into()
- .map_or(Self::BLACK, Self::from_number),
+ Value::Int(v) => Self::from_number(v.clamp(0, u16::MAX as i64) as u16),
Value::Str(string) => match string.as_str() {
"thin" => Self::THIN,
"extralight" => Self::EXTRALIGHT,
diff --git a/tests/fonts/IBMPlexSans-Medium.ttf b/tests/fonts/IBMPlexSans-Medium.ttf
new file mode 100644
index 00000000..9395402b
--- /dev/null
+++ b/tests/fonts/IBMPlexSans-Medium.ttf
Binary files differ
diff --git a/tests/ref/text/emphasis.png b/tests/ref/text/emphasis.png
index c004421d..da04d8d1 100644
--- a/tests/ref/text/emphasis.png
+++ b/tests/ref/text/emphasis.png
Binary files differ
diff --git a/tests/typ/text/emphasis.typ b/tests/typ/text/emphasis.typ
index cd2191cc..27e3b977 100644
--- a/tests/typ/text/emphasis.typ
+++ b/tests/typ/text/emphasis.typ
@@ -17,6 +17,16 @@ _Still [
P#strong[art]ly em#emph[phas]ized.
---
+// Adjusting the delta that strong applies on the weight.
+Normal
+
+#set strong(delta: 300)
+*Bold*
+
+#set strong(delta: 150)
+*Medium* and *[*Bold*]*
+
+---
// Error: 13 expected underscore
#box[_Scoped] to body.