summaryrefslogtreecommitdiff
path: root/src/library/text.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2021-12-20 14:18:29 +0100
committerLaurenz <laurmaedje@gmail.com>2021-12-21 00:20:24 +0100
commit11565a40b315212474f52eb576a9fd92b11f1132 (patch)
treec6b7afb35103065bc92b407094ca905bb75cfc73 /src/library/text.rs
parent958f74f77707340f34ee36d09492bdb74523aa2a (diff)
Set Rules Episode IX: The Rise of Testing
Diffstat (limited to 'src/library/text.rs')
-rw-r--r--src/library/text.rs116
1 files changed, 77 insertions, 39 deletions
diff --git a/src/library/text.rs b/src/library/text.rs
index e0cbb1ad..4ff9b5cd 100644
--- a/src/library/text.rs
+++ b/src/library/text.rs
@@ -56,11 +56,11 @@ impl TextNode {
/// A prioritized sequence of font families.
pub const FAMILY_LIST: Vec<FontFamily> = vec![FontFamily::SansSerif];
/// The serif font family/families.
- pub const SERIF_LIST: Vec<String> = vec!["ibm plex serif".into()];
+ pub const SERIF_LIST: Vec<NamedFamily> = vec![NamedFamily::new("IBM Plex Serif")];
/// The sans-serif font family/families.
- pub const SANS_SERIF_LIST: Vec<String> = vec!["ibm plex sans".into()];
+ pub const SANS_SERIF_LIST: Vec<NamedFamily> = vec![NamedFamily::new("IBM Plex Sans")];
/// The monospace font family/families.
- pub const MONOSPACE_LIST: Vec<String> = vec!["ibm plex mono".into()];
+ pub const MONOSPACE_LIST: Vec<NamedFamily> = vec![NamedFamily::new("IBM Plex Mono")];
/// Whether to allow font fallback when the primary font list contains no
/// match.
pub const FALLBACK: bool = true;
@@ -139,32 +139,38 @@ impl Set for TextNode {
(!families.is_empty()).then(|| families)
});
- set!(styles, Self::FAMILY_LIST => list);
- set!(styles, Self::SERIF_LIST => args.named("serif")?);
- set!(styles, Self::SANS_SERIF_LIST => args.named("sans-serif")?);
- set!(styles, Self::MONOSPACE_LIST => args.named("monospace")?);
- set!(styles, Self::FALLBACK => args.named("fallback")?);
- set!(styles, Self::STYLE => args.named("style")?);
- set!(styles, Self::WEIGHT => args.named("weight")?);
- set!(styles, Self::STRETCH => args.named("stretch")?);
- set!(styles, Self::FILL => args.named("fill")?.or_else(|| args.find()));
- set!(styles, Self::SIZE => args.named("size")?.or_else(|| args.find()));
- set!(styles, Self::TRACKING => args.named("tracking")?.map(Em::new));
- set!(styles, Self::TOP_EDGE => args.named("top-edge")?);
- set!(styles, Self::BOTTOM_EDGE => args.named("bottom-edge")?);
- set!(styles, Self::KERNING => args.named("kerning")?);
- set!(styles, Self::SMALLCAPS => args.named("smallcaps")?);
- set!(styles, Self::ALTERNATES => args.named("alternates")?);
- set!(styles, Self::STYLISTIC_SET => args.named("stylistic-set")?);
- set!(styles, Self::LIGATURES => args.named("ligatures")?);
- set!(styles, Self::DISCRETIONARY_LIGATURES => args.named("discretionary-ligatures")?);
- set!(styles, Self::HISTORICAL_LIGATURES => args.named("historical-ligatures")?);
- set!(styles, Self::NUMBER_TYPE => args.named("number-type")?);
- set!(styles, Self::NUMBER_WIDTH => args.named("number-width")?);
- set!(styles, Self::NUMBER_POSITION => args.named("number-position")?);
- set!(styles, Self::SLASHED_ZERO => args.named("slashed-zero")?);
- set!(styles, Self::FRACTIONS => args.named("fractions")?);
- set!(styles, Self::FEATURES => args.named("features")?);
+ styles.set_opt(Self::FAMILY_LIST, list);
+ styles.set_opt(Self::SERIF_LIST, args.named("serif")?);
+ styles.set_opt(Self::SANS_SERIF_LIST, args.named("sans-serif")?);
+ styles.set_opt(Self::MONOSPACE_LIST, args.named("monospace")?);
+ styles.set_opt(Self::FALLBACK, args.named("fallback")?);
+ styles.set_opt(Self::STYLE, args.named("style")?);
+ styles.set_opt(Self::WEIGHT, args.named("weight")?);
+ styles.set_opt(Self::STRETCH, args.named("stretch")?);
+ styles.set_opt(Self::FILL, args.named("fill")?.or_else(|| args.find()));
+ styles.set_opt(Self::SIZE, args.named("size")?.or_else(|| args.find()));
+ styles.set_opt(Self::TRACKING, args.named("tracking")?.map(Em::new));
+ styles.set_opt(Self::TOP_EDGE, args.named("top-edge")?);
+ styles.set_opt(Self::BOTTOM_EDGE, args.named("bottom-edge")?);
+ styles.set_opt(Self::KERNING, args.named("kerning")?);
+ styles.set_opt(Self::SMALLCAPS, args.named("smallcaps")?);
+ styles.set_opt(Self::ALTERNATES, args.named("alternates")?);
+ styles.set_opt(Self::STYLISTIC_SET, args.named("stylistic-set")?);
+ styles.set_opt(Self::LIGATURES, args.named("ligatures")?);
+ styles.set_opt(
+ Self::DISCRETIONARY_LIGATURES,
+ args.named("discretionary-ligatures")?,
+ );
+ styles.set_opt(
+ Self::HISTORICAL_LIGATURES,
+ args.named("historical-ligatures")?,
+ );
+ styles.set_opt(Self::NUMBER_TYPE, args.named("number-type")?);
+ styles.set_opt(Self::NUMBER_WIDTH, args.named("number-width")?);
+ styles.set_opt(Self::NUMBER_POSITION, args.named("number-position")?);
+ styles.set_opt(Self::SLASHED_ZERO, args.named("slashed-zero")?);
+ styles.set_opt(Self::FRACTIONS, args.named("fractions")?);
+ styles.set_opt(Self::FEATURES, args.named("features")?);
Ok(())
}
@@ -188,8 +194,15 @@ pub enum FontFamily {
SansSerif,
/// A family in which (almost) all glyphs are of equal width.
Monospace,
- /// A specific family with a name.
- Named(String),
+ /// A specific font family like "Arial".
+ Named(NamedFamily),
+}
+
+impl FontFamily {
+ /// Create a named font family variant, directly from a string.
+ pub fn named(string: &str) -> Self {
+ Self::Named(NamedFamily::new(string))
+ }
}
impl Debug for FontFamily {
@@ -203,15 +216,37 @@ impl Debug for FontFamily {
}
}
+/// A specific font family like "Arial".
+#[derive(Clone, Eq, PartialEq, Hash)]
+pub struct NamedFamily(String);
+
+impl NamedFamily {
+ /// Create a named font family variant.
+ pub fn new(string: &str) -> Self {
+ Self(string.to_lowercase())
+ }
+
+ /// The lowercased family name.
+ pub fn as_str(&self) -> &str {
+ &self.0
+ }
+}
+
+impl Debug for NamedFamily {
+ fn fmt(&self, f: &mut Formatter) -> fmt::Result {
+ self.0.fmt(f)
+ }
+}
+
dynamic! {
FontFamily: "font family",
- Value::Str(string) => Self::Named(string.to_lowercase().into()),
+ Value::Str(string) => Self::named(&string),
}
castable! {
Vec<FontFamily>,
Expected: "string, generic family or array thereof",
- Value::Str(string) => vec![FontFamily::Named(string.to_lowercase().into())],
+ Value::Str(string) => vec![FontFamily::named(&string)],
Value::Array(values) => {
values.into_iter().filter_map(|v| v.cast().ok()).collect()
},
@@ -219,13 +254,13 @@ castable! {
}
castable! {
- Vec<String>,
+ Vec<NamedFamily>,
Expected: "string or array of strings",
- Value::Str(string) => vec![string.to_lowercase().into()],
+ Value::Str(string) => vec![NamedFamily::new(&string)],
Value::Array(values) => values
.into_iter()
.filter_map(|v| v.cast().ok())
- .map(|string: EcoString| string.to_lowercase().into())
+ .map(|string: EcoString| NamedFamily::new(&string))
.collect(),
}
@@ -243,7 +278,10 @@ castable! {
castable! {
FontWeight,
Expected: "integer or string",
- Value::Int(v) => v.try_into().map_or(Self::BLACK, Self::from_number),
+ Value::Int(v) => Value::Int(v)
+ .cast::<usize>()?
+ .try_into()
+ .map_or(Self::BLACK, Self::from_number),
Value::Str(string) => match string.as_str() {
"thin" => Self::THIN,
"extralight" => Self::EXTRALIGHT,
@@ -681,7 +719,7 @@ fn families(styles: &Styles) -> impl Iterator<Item = &str> + Clone {
head.iter()
.chain(core)
- .map(String::as_str)
+ .map(|named| named.as_str())
.chain(tail.iter().copied())
}
@@ -770,7 +808,7 @@ pub struct ShapedText<'a> {
/// The text direction.
pub dir: Dir,
/// The text's style properties.
- // TODO(set): Go back to reference.
+ // TODO(style): Go back to reference.
pub styles: Styles,
/// The font size.
pub size: Size,