diff --git a/crates/typst/src/text/font/book.rs b/crates/typst/src/text/font/book.rs index b84d05cbf..131e666fe 100644 --- a/crates/typst/src/text/font/book.rs +++ b/crates/typst/src/text/font/book.rs @@ -51,6 +51,11 @@ impl FontBook { self.infos.get(index) } + /// Returns true if the book contains a font family with the given name. + pub fn contains_family(&self, family: &str) -> bool { + self.families.contains_key(family) + } + /// An ordered iterator over all font families this book knows and details /// about the fonts that are part of them. pub fn families( diff --git a/crates/typst/src/text/mod.rs b/crates/typst/src/text/mod.rs index f7c19d8e6..ef621ee56 100644 --- a/crates/typst/src/text/mod.rs +++ b/crates/typst/src/text/mod.rs @@ -35,7 +35,7 @@ use rustybuzz::{Feature, Tag}; use smallvec::SmallVec; use ttf_parser::Rect; -use crate::diag::{bail, SourceResult, StrResult}; +use crate::diag::{bail, warning, SourceResult, StrResult}; use crate::engine::Engine; use crate::foundations::Packed; use crate::foundations::{ @@ -47,6 +47,7 @@ use crate::layout::{Abs, Axis, Dir, Length, Rel}; use crate::model::ParElem; use crate::syntax::Spanned; use crate::visualize::{Color, Paint, RelativeTo, Stroke}; +use crate::World; /// Text styling. /// @@ -122,6 +123,22 @@ pub struct TextElem { /// This is Latin. \ /// هذا عربي. /// ``` + #[parse({ + let font_list: Option> = args.named("font")?; + if let Some(font_list) = &font_list { + let book = engine.world.book(); + for family in &font_list.v { + if !book.contains_family(family.as_str()) { + engine.tracer.warn(warning!( + font_list.span, + "unknown font family: {}", + family.as_str(), + )); + } + } + } + font_list.map(|font_list| font_list.v) + })] #[default(FontList(vec![FontFamily::new("Linux Libertine")]))] #[borrowed] #[ghost] diff --git a/tests/ref/text-unknown-font-family-warning.png b/tests/ref/text-unknown-font-family-warning.png new file mode 100644 index 000000000..a46632cfd Binary files /dev/null and b/tests/ref/text-unknown-font-family-warning.png differ diff --git a/tests/suite/math/interactions.typ b/tests/suite/math/interactions.typ index 37185962c..03d5a6e7f 100644 --- a/tests/suite/math/interactions.typ +++ b/tests/suite/math/interactions.typ @@ -17,6 +17,7 @@ $ x := #table(columns: 2)[x][y]/mat(1, 2, 3) --- math-font-switch --- // Test font switch. +// Warning: 29-40 unknown font family: noto sans #let here = text.with(font: "Noto Sans") $#here[f] := #here[Hi there]$. diff --git a/tests/suite/text/edge.typ b/tests/suite/text/edge.typ index 57732156c..9ee9bd2f9 100644 --- a/tests/suite/text/edge.typ +++ b/tests/suite/text/edge.typ @@ -5,11 +5,13 @@ #set text(size: 8pt) #let try(top, bottom) = rect(inset: 0pt, fill: conifer)[ + // Warning: 19-34 unknown font family: ibm plex mono #set text(font: "IBM Plex Mono", top-edge: top, bottom-edge: bottom) From #top to #bottom ] #let try-bounds(top, bottom) = rect(inset: 0pt, fill: conifer)[ + // Warning: 19-34 unknown font family: ibm plex mono #set text(font: "IBM Plex Mono", top-edge: top, bottom-edge: bottom) #top to #bottom: "yay, Typst" ] diff --git a/tests/suite/text/font.typ b/tests/suite/text/font.typ index 47ec64191..ecc4c5c78 100644 --- a/tests/suite/text/font.typ +++ b/tests/suite/text/font.typ @@ -64,3 +64,15 @@ Emoji: 🐪, 🌋, 🏞 --- text-bad-named-argument --- // Error: 11-31 unexpected argument: something #set text(something: "invalid") + +--- text-unknown-font-family-warning --- +#text(font: "linux libertine", "I exist, ") +// Warning: 13-27 unknown font family: non-existing +#text(font: "non-existing", "but") +// Warning: 17-36 unknown font family: also-non-existing +#set text(font: "also-non-existing") +I +// Warning: 23-56 unknown font family: list-of +// Warning: 23-56 unknown font family: non-existing-fonts +#let var = text(font: ("list-of", "non-existing-fonts"))[don't] +#var