From 072e7c710c763904ad3ee72cfb05252f9f0d3929 Mon Sep 17 00:00:00 2001 From: Laurenz Date: Mon, 1 Nov 2021 13:07:11 +0100 Subject: [PATCH] Reduce namespace pollution --- src/font.rs | 58 ++++++----------------------------- src/library/mod.rs | 37 +--------------------- src/library/page.rs | 3 +- src/library/text.rs | 56 +++++++++++++++++++++++++++++++-- src/library/utility.rs | 2 +- src/loading/fs.rs | 1 + tests/typ/code/call.typ | 2 +- tests/typ/code/spread.typ | 10 +++--- tests/typ/elements/square.typ | 2 +- tests/typ/text/font.typ | 28 +++++++++++------ tests/typ/utility/color.typ | 2 +- 11 files changed, 93 insertions(+), 108 deletions(-) diff --git a/src/font.rs b/src/font.rs index 8519d4501..378115e49 100644 --- a/src/font.rs +++ b/src/font.rs @@ -283,7 +283,7 @@ impl Face { } /// Identifies a vertical metric of a font. -#[derive(Copy, Clone, Eq, PartialEq, Hash)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] pub enum VerticalFontMetric { /// The distance from the baseline to the typographic ascender. /// @@ -306,19 +306,6 @@ pub enum VerticalFontMetric { Linear(Linear), } -impl Debug for VerticalFontMetric { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match self { - Self::Ascender => f.pad("ascender"), - Self::CapHeight => f.pad("cap-height"), - Self::XHeight => f.pad("x-height"), - Self::Baseline => f.pad("baseline"), - Self::Descender => f.pad("descender"), - Self::Linear(v) => v.fmt(f), - } - } -} - /// A generic or named font family. #[derive(Clone, Eq, PartialEq, Hash)] pub enum FontFamily { @@ -438,7 +425,7 @@ impl Debug for FontVariant { } /// The style of a font face. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] +#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum FontStyle { @@ -456,16 +443,6 @@ impl Default for FontStyle { } } -impl Debug for FontStyle { - fn fmt(&self, f: &mut Formatter) -> fmt::Result { - f.pad(match self { - Self::Normal => "normal", - Self::Italic => "italic", - Self::Oblique => "oblique", - }) - } -} - /// The weight of a font face. #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] #[derive(Serialize, Deserialize)] @@ -530,18 +507,7 @@ impl Default for FontWeight { impl Debug for FontWeight { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match *self { - Self::THIN => f.pad("thin"), - Self::EXTRALIGHT => f.pad("extralight"), - Self::LIGHT => f.pad("light"), - Self::REGULAR => f.pad("regular"), - Self::MEDIUM => f.pad("medium"), - Self::SEMIBOLD => f.pad("semibold"), - Self::BOLD => f.pad("bold"), - Self::EXTRABOLD => f.pad("extrabold"), - Self::BLACK => f.pad("black"), - _ => write!(f, "{}", self.0), - } + write!(f, "{}", self.0) } } @@ -620,18 +586,7 @@ impl Default for FontStretch { impl Debug for FontStretch { fn fmt(&self, f: &mut Formatter) -> fmt::Result { - match *self { - Self::ULTRA_CONDENSED => f.pad("ultra-condensed"), - Self::EXTRA_CONDENSED => f.pad("extra-condensed"), - Self::CONDENSED => f.pad("condensed"), - Self::SEMI_CONDENSED => f.pad("semi-condensed"), - Self::NORMAL => f.pad("normal"), - Self::SEMI_EXPANDED => f.pad("semi-expanded"), - Self::EXPANDED => f.pad("expanded"), - Self::EXTRA_EXPANDED => f.pad("extra-expanded"), - Self::ULTRA_EXPANDED => f.pad("ultra-expanded"), - _ => write!(f, "{}", self.to_ratio()), - } + write!(f, "{}%", 100.0 * self.to_ratio()) } } @@ -647,4 +602,9 @@ mod tests { assert_eq!(d(500, 900), 400); assert_eq!(d(10, 100), 90); } + + #[test] + fn test_font_stretch_debug() { + assert_eq!(format!("{:?}", FontStretch::EXPANDED), "125%") + } } diff --git a/src/library/mod.rs b/src/library/mod.rs index c0b6f2b86..b0a42e835 100644 --- a/src/library/mod.rs +++ b/src/library/mod.rs @@ -46,10 +46,8 @@ pub use text::*; pub use transform::*; pub use utility::*; -use std::convert::TryFrom; - use crate::eval::{Scope, Value}; -use crate::font::{FontFamily, FontStretch, FontStyle, FontWeight, VerticalFontMetric}; +use crate::font::FontFamily; use crate::geom::*; /// Construct a scope containing all standard library definitions. @@ -125,16 +123,6 @@ pub fn new() -> Scope { std.def_const("serif", FontFamily::Serif); std.def_const("sans-serif", FontFamily::SansSerif); std.def_const("monospace", FontFamily::Monospace); - std.def_const("normal", FontStyle::Normal); - std.def_const("italic", FontStyle::Italic); - std.def_const("oblique", FontStyle::Oblique); - std.def_const("regular", FontWeight::REGULAR); - std.def_const("bold", FontWeight::BOLD); - std.def_const("ascender", VerticalFontMetric::Ascender); - std.def_const("cap-height", VerticalFontMetric::CapHeight); - std.def_const("x-height", VerticalFontMetric::XHeight); - std.def_const("baseline", VerticalFontMetric::Baseline); - std.def_const("descender", VerticalFontMetric::Descender); std } @@ -151,26 +139,3 @@ dynamic! { FontFamily: "font family", Value::Str(string) => Self::Named(string.to_lowercase()), } - -dynamic! { - FontStyle: "font style", -} - -dynamic! { - FontWeight: "font weight", - Value::Int(v) => { - u16::try_from(v).map_or(Self::BLACK, Self::from_number) - }, -} - -dynamic! { - FontStretch: "font stretch", - Value::Relative(v) => Self::from_ratio(v.get() as f32), -} - -dynamic! { - VerticalFontMetric: "vertical font metric", - Value::Length(v) => Self::Linear(v.into()), - Value::Relative(v) => Self::Linear(v.into()), - Value::Linear(v) => Self::Linear(v), -} diff --git a/src/library/page.rs b/src/library/page.rs index 9dcb5ba3d..b31a32a38 100644 --- a/src/library/page.rs +++ b/src/library/page.rs @@ -5,8 +5,7 @@ use crate::style::{Paper, PaperClass}; pub fn page(ctx: &mut EvalContext, args: &mut Args) -> TypResult { castable! { Paper: "string", - Value::Str(string) => Paper::from_name(&string) - .ok_or("invalid paper name")?, + Value::Str(string) => Paper::from_name(&string).ok_or("unknown paper")?, } let paper = args.named::("paper")?.or_else(|| args.find()); diff --git a/src/library/text.rs b/src/library/text.rs index 17b33ca58..e55ba4830 100644 --- a/src/library/text.rs +++ b/src/library/text.rs @@ -1,10 +1,14 @@ use std::borrow::Cow; +use std::convert::TryInto; use std::ops::Range; use rustybuzz::{Feature, Tag, UnicodeBuffer}; use super::prelude::*; -use crate::font::{Face, FaceId, FontFamily, FontVariant}; +use crate::font::{ + Face, FaceId, FontFamily, FontStretch, FontStyle, FontVariant, FontWeight, + VerticalFontMetric, +}; use crate::geom::{Dir, Em, Length, Point, Size}; use crate::style::{ FontFeatures, NumberPosition, NumberStyle, NumberWidth, Style, TextStyle, @@ -42,11 +46,58 @@ pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult { )), } + castable! { + FontStyle: "string", + Value::Str(string) => match string.as_str() { + "normal" => Self::Normal, + "italic" => Self::Italic, + "oblique" => Self::Oblique, + _ => Err(r#"expected "normal", "italic" or "oblique""#)?, + }, + } + + castable! { + FontWeight: "integer or string", + Value::Int(v) => v.try_into().map_or(Self::BLACK, Self::from_number), + Value::Str(string) => match string.as_str() { + "thin" => Self::THIN, + "extralight" => Self::EXTRALIGHT, + "light" => Self::LIGHT, + "regular" => Self::REGULAR, + "medium" => Self::MEDIUM, + "semibold" => Self::SEMIBOLD, + "bold" => Self::BOLD, + "extrabold" => Self::EXTRABOLD, + "black" => Self::BLACK, + _ => Err("unknown font weight")?, + }, + } + + castable! { + FontStretch: "relative", + Value::Relative(v) => Self::from_ratio(v.get() as f32), + } + + castable! { + VerticalFontMetric: "linear or string", + Value::Length(v) => Self::Linear(v.into()), + Value::Relative(v) => Self::Linear(v.into()), + Value::Linear(v) => Self::Linear(v), + Value::Str(string) => match string.as_str() { + "ascender" => Self::Ascender, + "cap-height" => Self::CapHeight, + "x-height" => Self::XHeight, + "baseline" => Self::Baseline, + "descender" => Self::Descender, + _ => Err("unknown font metric")?, + }, + } + castable! { StylisticSet: "none or integer", Value::None => Self(None), Value::Int(v) => match v { - 1..=20 => Self(Some(v as u8)), + 1 ..= 20 => Self(Some(v as u8)), _ => Err("must be between 1 and 20")?, }, } @@ -109,6 +160,7 @@ pub fn font(ctx: &mut EvalContext, args: &mut Args) -> TypResult { let sans_serif = args.named("sans-serif")?; let monospace = args.named("monospace")?; let fallback = args.named("fallback")?; + let size = args.named::("size")?.or_else(|| args.find()); let style = args.named("style")?; let weight = args.named("weight")?; diff --git a/src/library/utility.rs b/src/library/utility.rs index 05b7639bc..69ae235d5 100644 --- a/src/library/utility.rs +++ b/src/library/utility.rs @@ -90,7 +90,7 @@ pub fn rgb(_: &mut EvalContext, args: &mut Args) -> TypResult { if let Some(string) = args.find::>() { match RgbaColor::from_str(&string.v) { Ok(color) => color, - Err(_) => bail!(string.span, "invalid color"), + Err(_) => bail!(string.span, "invalid hex string"), } } else { let r = args.expect("red component")?; diff --git a/src/loading/fs.rs b/src/loading/fs.rs index 34d8e9b5a..ed544ba7b 100644 --- a/src/loading/fs.rs +++ b/src/loading/fs.rs @@ -169,6 +169,7 @@ mod tests { Path::new("fonts/NotoSerifHebrew-Bold.ttf"), Path::new("fonts/NotoSerifHebrew-Regular.ttf"), Path::new("fonts/PTSans-Regular.ttf"), + Path::new("fonts/Roboto-Regular.ttf"), Path::new("fonts/TwitterColorEmoji.ttf"), ]); } diff --git a/tests/typ/code/call.typ b/tests/typ/code/call.typ index 5ab0252c0..2c16af1cf 100644 --- a/tests/typ/code/call.typ +++ b/tests/typ/code/call.typ @@ -5,7 +5,7 @@ // Ref: true // Ommitted space. -[#font(weight:bold)Bold] +[#font(weight:"bold")Bold] // Call return value of function with body. #let f(x, body) = (y) => [#x] + body + [#y] diff --git a/tests/typ/code/spread.typ b/tests/typ/code/spread.typ index 4e7e0ad81..8a9491d06 100644 --- a/tests/typ/code/spread.typ +++ b/tests/typ/code/spread.typ @@ -4,14 +4,14 @@ --- // Test standard argument overriding. { - let font(style: normal, weight: regular) = { - "(style: " + repr(style) + ", weight: " + repr(weight) + ")" + let font(style: "normal", weight: "regular") = { + "(style: " + style + ", weight: " + weight + ")" } - let myfont(..args) = font(weight: bold, ..args) + let myfont(..args) = font(weight: "bold", ..args) test(myfont(), "(style: normal, weight: bold)") - test(myfont(weight: 100), "(style: normal, weight: 100)") - test(myfont(style: italic), "(style: italic, weight: bold)") + test(myfont(weight: "black"), "(style: normal, weight: black)") + test(myfont(style: "italic"), "(style: italic, weight: bold)") } --- diff --git a/tests/typ/elements/square.typ b/tests/typ/elements/square.typ index 0e9c3c55d..3686debb9 100644 --- a/tests/typ/elements/square.typ +++ b/tests/typ/elements/square.typ @@ -8,7 +8,7 @@ --- // Test auto-sized square. #square(fill: eastern)[ - #font(fill: white, weight: bold) + #font(fill: white, weight: "bold") #align(center) #pad(5pt)[Typst] ] diff --git a/tests/typ/text/font.typ b/tests/typ/text/font.typ index 3c8fcaf14..5c97d3678 100644 --- a/tests/typ/text/font.typ +++ b/tests/typ/text/font.typ @@ -10,10 +10,10 @@ #font()[Normal] // Set style (is available). -#font(style: italic)[Italic] +#font(style: "italic")[Italic] // Set weight (is available). -#font(weight: bold)[Bold] +#font(weight: "bold")[Bold] // Set stretch (not available, matching closest). #font(stretch: 50%)[Condensed] @@ -52,14 +52,14 @@ Emoji: 🐪, 🌋, 🏞 #font(size: 8pt) #let try(top, bottom) = rect(fill: conifer)[ - #font(top-edge: top, bottom-edge: bottom) - `From `#top` to `#bottom + #font(monospace, top-edge: top, bottom-edge: bottom) + From #top to #bottom ] -#try(ascender, descender) -#try(ascender, baseline) -#try(cap-height, baseline) -#try(x-height, baseline) +#try("ascender", "descender") +#try("ascender", "baseline") +#try("cap-height", "baseline") +#try("x-height", "baseline") #try(4pt, -2pt) #try(1pt + 27%, -18%) @@ -68,8 +68,16 @@ Emoji: 🐪, 🌋, 🏞 #font(false) --- -// Error: 14-18 expected font style, found font weight -#font(style: bold, weight: "thin") +// Error: 14-20 expected "normal", "italic" or "oblique" +#font(style: "bold", weight: "thin") + +--- +// Error: 17-19 expected linear or string, found array +#font(top-edge: ()) + +--- +// Error: 17-19 unknown font metric +#font(top-edge: "") --- // Error: 14-15 expected string or array of strings, found integer diff --git a/tests/typ/utility/color.typ b/tests/typ/utility/color.typ index 54316a372..759672ff2 100644 --- a/tests/typ/utility/color.typ +++ b/tests/typ/utility/color.typ @@ -19,7 +19,7 @@ #test(rgb(0.1, 0.2, 0.3, -0.1)) --- -// Error: 6-11 invalid color +// Error: 6-11 invalid hex string #rgb("lol") ---