diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a649b53c6..bdea4128f 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -6,6 +6,9 @@ on: pull_request: branches: [master] +env: + CARGO_TERM_COLOR: always + jobs: ci: runs-on: ubuntu-latest diff --git a/src/compute/value.rs b/src/compute/value.rs index ce7e8d577..975c1f463 100644 --- a/src/compute/value.rs +++ b/src/compute/value.rs @@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Formatter}; use std::ops::Deref; use std::rc::Rc; -use fontdock::{FontStyle, FontWeight, FontWidth}; +use fontdock::{FontStretch, FontStyle, FontWeight}; use super::table::{SpannedEntry, Table}; use crate::color::RgbaColor; @@ -390,8 +390,9 @@ impl_ident!(SpecAlign, "alignment", |s| match s { _ => None, }); -impl_ident!(FontStyle, "font style", FontStyle::from_name); -impl_ident!(Paper, "paper", Paper::from_name); +impl_ident!(FontStyle, "font style", Self::from_str); +impl_ident!(FontStretch, "font stretch", Self::from_str); +impl_ident!(Paper, "paper", Self::from_name); impl TryFromValue for FontWeight { fn try_from_value(value: Spanned<&Value>, f: &mut Feedback) -> Option { @@ -400,18 +401,18 @@ impl TryFromValue for FontWeight { const MIN: u16 = 100; const MAX: u16 = 900; - Some(Self(if weight < MIN as f64 { + if weight < MIN as f64 { error!(@f, value.span, "the minimum font weight is {}", MIN); - MIN + Some(Self::THIN) } else if weight > MAX as f64 { error!(@f, value.span, "the maximum font weight is {}", MAX); - MAX + Some(Self::BLACK) } else { - weight.round() as u16 - })) + FontWeight::from_number(weight.round() as u16) + } } Value::Ident(ident) => { - let weight = Self::from_name(ident.as_str()); + let weight = Self::from_str(ident.as_str()); if weight.is_none() { error!(@f, value.span, "invalid font weight"); } @@ -429,42 +430,6 @@ impl TryFromValue for FontWeight { } } -impl TryFromValue for FontWidth { - fn try_from_value(value: Spanned<&Value>, f: &mut Feedback) -> Option { - match value.v { - &Value::Number(width) => { - const MIN: u16 = 1; - const MAX: u16 = 9; - - Self::new(if width < MIN as f64 { - error!(@f, value.span, "the minimum font width is {}", MIN); - MIN - } else if width > MAX as f64 { - error!(@f, value.span, "the maximum font width is {}", MAX); - MAX - } else { - width.round() as u16 - }) - } - Value::Ident(ident) => { - let width = Self::from_name(ident.as_str()); - if width.is_none() { - error!(@f, value.span, "invalid font width"); - } - width - } - other => { - error!( - @f, value.span, - "expected font width (name or number), found {}", - other.name(), - ); - None - } - } - } -} - #[cfg(test)] mod tests { use super::*; diff --git a/src/layout/text.rs b/src/layout/text.rs index a43437b1d..971d6be67 100644 --- a/src/layout/text.rs +++ b/src/layout/text.rs @@ -120,7 +120,7 @@ impl<'a> TextLayouter<'a> { let mut variant = self.ctx.style.variant; if self.ctx.style.bolder { - variant.weight.0 += 300; + variant.weight = variant.weight.thicken(300); } if self.ctx.style.italic { diff --git a/src/layout/tree.rs b/src/layout/tree.rs index faecc42b7..fe12cc337 100644 --- a/src/layout/tree.rs +++ b/src/layout/tree.rs @@ -131,7 +131,7 @@ impl<'a> TreeLayouter<'a> { async fn layout_raw(&mut self, lines: &[String]) { // TODO: Make this more efficient. let fallback = self.style.text.fallback.clone(); - self.style.text.fallback.list_mut().insert(0, "monospace".to_string()); + self.style.text.fallback.list.insert(0, "monospace".to_string()); self.style.text.fallback.flatten(); let mut first = true; diff --git a/src/library/font.rs b/src/library/font.rs index e3caeded1..ed9360e01 100644 --- a/src/library/font.rs +++ b/src/library/font.rs @@ -1,4 +1,4 @@ -use fontdock::{FontStyle, FontWeight, FontWidth}; +use fontdock::{FontStretch, FontStyle, FontWeight}; use super::*; use crate::length::ScaleLength; @@ -12,7 +12,7 @@ use crate::length::ScaleLength; /// # Keyword arguments /// - `style`: `normal`, `italic` or `oblique`. /// - `weight`: `100` - `900` or a name like `thin`. -/// - `width`: `1` - `9` or a name like `condensed`. +/// - `width`: `normal`, `condensed`, `expanded`, ... /// - Any other keyword argument whose value is a table of strings is a class /// fallback definition like: /// ```typst @@ -41,7 +41,7 @@ pub async fn font(_: Span, mut args: TableValue, ctx: LayoutContext<'_>) -> Pass .collect(); if !list.is_empty() { - *text.fallback.list_mut() = list; + text.fallback.list = list; updated_fallback = true; } @@ -53,8 +53,8 @@ pub async fn font(_: Span, mut args: TableValue, ctx: LayoutContext<'_>) -> Pass text.variant.weight = weight; } - if let Some(width) = args.take_key::("width", &mut f) { - text.variant.width = width; + if let Some(stretch) = args.take_key::("stretch", &mut f) { + text.variant.stretch = stretch; } for (class, mut table) in args.take_all_str::() { @@ -63,7 +63,7 @@ pub async fn font(_: Span, mut args: TableValue, ctx: LayoutContext<'_>) -> Pass .map(|s| s.to_lowercase()) .collect(); - text.fallback.set_class_list(class, fallback); + text.fallback.update_class_list(class, fallback); updated_fallback = true; } diff --git a/src/style.rs b/src/style.rs index e964103a6..9402f11d1 100644 --- a/src/style.rs +++ b/src/style.rs @@ -1,6 +1,6 @@ //! Styles for text and pages. -use fontdock::{fallback, FallbackTree, FontStyle, FontVariant, FontWeight, FontWidth}; +use fontdock::{fallback, FallbackTree, FontStretch, FontStyle, FontVariant, FontWeight}; use crate::geom::{Margins, Size, Value4}; use crate::length::{Length, ScaleLength}; @@ -80,8 +80,8 @@ impl Default for TextStyle { }, variant: FontVariant { style: FontStyle::Normal, - weight: FontWeight(400), - width: FontWidth::Medium, + weight: FontWeight::REGULAR, + stretch: FontStretch::Normal, }, bolder: false, italic: false,