summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/eval/state.rs47
-rw-r--r--src/library/text.rs5
-rw-r--r--tests/ref/text/font.pngbin21435 -> 22712 bytes
-rw-r--r--tests/typ/text/font.typ19
4 files changed, 44 insertions, 27 deletions
diff --git a/src/eval/state.rs b/src/eval/state.rs
index 2037c695..b6c0c9af 100644
--- a/src/eval/state.rs
+++ b/src/eval/state.rs
@@ -119,13 +119,6 @@ impl Default for ParState {
/// Defines font properties.
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct FontState {
- /// Whether 300 extra font weight should be added to what is defined by the
- /// `variant`.
- pub strong: bool,
- /// Whether the the font style defined by the `variant` should be inverted.
- pub emph: bool,
- /// Whether a monospace font should be preferred.
- pub monospace: bool,
/// The font size.
pub size: Length,
/// The selected font variant (the final variant also depends on `strong`
@@ -140,6 +133,15 @@ pub struct FontState {
/// A list of font families with generic class definitions (the final
/// family list also depends on `monospace`).
pub families: Rc<FamilyState>,
+ /// Whether 300 extra font weight should be added to what is defined by the
+ /// `variant`.
+ pub strong: bool,
+ /// Whether the the font style defined by the `variant` should be inverted.
+ pub emph: bool,
+ /// Whether a monospace font should be preferred.
+ pub monospace: bool,
+ /// Whether font fallback to a base list should occur.
+ pub fallback: bool,
}
impl FontState {
@@ -164,10 +166,11 @@ impl FontState {
/// The resolved family iterator.
pub fn families(&self) -> impl Iterator<Item = &str> + Clone {
- let head = self
- .monospace
- .then(|| self.families.monospace.as_slice())
- .unwrap_or_default();
+ let head = if self.monospace {
+ self.families.monospace.as_slice()
+ } else {
+ &[]
+ };
let core = self.families.list.iter().flat_map(move |family| {
match family {
@@ -178,10 +181,13 @@ impl FontState {
}
});
- head.iter()
- .chain(core)
- .chain(self.families.base.iter())
- .map(String::as_str)
+ let tail = if self.fallback {
+ self.families.base.as_slice()
+ } else {
+ &[]
+ };
+
+ head.iter().chain(core).chain(tail).map(String::as_str)
}
/// Access the `families` state mutably.
@@ -193,19 +199,20 @@ impl FontState {
impl Default for FontState {
fn default() -> Self {
Self {
- families: Rc::new(FamilyState::default()),
+ size: Length::pt(11.0),
variant: FontVariant {
style: FontStyle::Normal,
weight: FontWeight::REGULAR,
stretch: FontStretch::NORMAL,
},
- strong: false,
- emph: false,
- monospace: false,
- size: Length::pt(11.0),
top_edge: VerticalFontMetric::CapHeight,
bottom_edge: VerticalFontMetric::Baseline,
fill: Paint::Color(Color::Rgba(RgbaColor::BLACK)),
+ families: Rc::new(FamilyState::default()),
+ strong: false,
+ emph: false,
+ monospace: false,
+ fallback: true,
}
}
}
diff --git a/src/library/text.rs b/src/library/text.rs
index f3e086c8..f12794aa 100644
--- a/src/library/text.rs
+++ b/src/library/text.rs
@@ -19,6 +19,7 @@ pub fn font(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
let serif = args.named("serif")?;
let sans_serif = args.named("sans-serif")?;
let monospace = args.named("monospace")?;
+ let fallback = args.named("fallback")?;
ctx.template.modify(move |state| {
let font = state.font_mut();
@@ -66,6 +67,10 @@ pub fn font(ctx: &mut EvalContext, args: &mut Arguments) -> TypResult<Value> {
if let Some(FamilyDef(monospace)) = &monospace {
font.families_mut().monospace = monospace.clone();
}
+
+ if let Some(fallback) = fallback {
+ font.fallback = fallback;
+ }
});
Ok(Value::None)
diff --git a/tests/ref/text/font.png b/tests/ref/text/font.png
index 44183b3a..b8e0775a 100644
--- a/tests/ref/text/font.png
+++ b/tests/ref/text/font.png
Binary files differ
diff --git a/tests/typ/text/font.typ b/tests/typ/text/font.typ
index fbb999f8..ecc07886 100644
--- a/tests/typ/text/font.typ
+++ b/tests/typ/text/font.typ
@@ -33,6 +33,18 @@ Emoji: 🐪, 🌋, 🏞
This is [#font(fill: rgb("FA644B")) way more] colorful.
]
+// Disable font fallback beyond the user-specified list.
+// Without disabling, Latin Modern Math would come to the rescue.
+#font("PT Sans", "Twitter Color Emoji", fallback: false)
+2π = 𝛼 + 𝛽. ✅
+
+---
+// Test class definitions.
+#font(sans-serif: "PT Sans")
+[#font(family: sans-serif) Sans-serif.] \
+[#font(monospace) Monospace.] \
+[#font(monospace, monospace: ("Nope", "Latin Modern Math")) Math.]
+
---
// Test top and bottom edge.
@@ -48,13 +60,6 @@ Emoji: 🐪, 🌋, 🏞
#try(x-height, baseline)
---
-// Test class definitions.
-#font(sans-serif: "PT Sans")
-[#font(family: sans-serif) Sans-serif.] \
-[#font(monospace) Monospace.] \
-[#font(monospace, monospace: ("Nope", "Latin Modern Math")) Math.]
-
----
// Error: 7-12 unexpected argument
#font(false)