summaryrefslogtreecommitdiff
path: root/src/font
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-03-07 15:17:13 +0100
committerLaurenz <laurmaedje@gmail.com>2023-03-07 15:17:13 +0100
commit25b5bd117529cd04bb789e1988eb3a3db8025a0e (patch)
tree2fbb4650903123da047a1f1f11a0abda95286e12 /src/font
parent6ab7760822ccd24b4ef126d4737d41f1be15fe19 (diff)
Fully untyped model
Diffstat (limited to 'src/font')
-rw-r--r--src/font/mod.rs25
-rw-r--r--src/font/variant.rs80
2 files changed, 99 insertions, 6 deletions
diff --git a/src/font/mod.rs b/src/font/mod.rs
index bedc107d..94ec170e 100644
--- a/src/font/mod.rs
+++ b/src/font/mod.rs
@@ -12,6 +12,7 @@ use std::sync::Arc;
use ttf_parser::GlyphId;
+use crate::eval::{cast_from_value, cast_to_value, Value};
use crate::geom::Em;
use crate::util::Buffer;
@@ -249,3 +250,27 @@ pub enum VerticalFontMetric {
/// present and falls back to the descender from the `hhea` table otherwise.
Descender,
}
+
+cast_from_value! {
+ VerticalFontMetric,
+ /// The font's ascender, which typically exceeds the height of all glyphs.
+ "ascender" => Self::Ascender,
+ /// The approximate height of uppercase letters.
+ "cap-height" => Self::CapHeight,
+ /// The approximate height of non-ascending lowercase letters.
+ "x-height" => Self::XHeight,
+ /// The baseline on which the letters rest.
+ "baseline" => Self::Baseline,
+ /// The font's ascender, which typically exceeds the depth of all glyphs.
+ "descender" => Self::Descender,
+}
+
+cast_to_value! {
+ v: VerticalFontMetric => Value::from(match v {
+ VerticalFontMetric::Ascender => "ascender",
+ VerticalFontMetric::CapHeight => "cap-height",
+ VerticalFontMetric::XHeight => "x-height",
+ VerticalFontMetric::Baseline => "baseline" ,
+ VerticalFontMetric::Descender => "descender",
+ })
+}
diff --git a/src/font/variant.rs b/src/font/variant.rs
index aa9ff141..4eda80ad 100644
--- a/src/font/variant.rs
+++ b/src/font/variant.rs
@@ -2,6 +2,9 @@ use std::fmt::{self, Debug, Formatter};
use serde::{Deserialize, Serialize};
+use crate::eval::{cast_from_value, cast_to_value, Value};
+use crate::geom::Ratio;
+
/// Properties that distinguish a font from other fonts in the same family.
#[derive(Default, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
@@ -59,6 +62,24 @@ impl Default for FontStyle {
}
}
+cast_from_value! {
+ FontStyle,
+ /// The default, typically upright style.
+ "normal" => Self::Normal,
+ /// A cursive style with custom letterform.
+ "italic" => Self::Italic,
+ /// Just a slanted version of the normal style.
+ "oblique" => Self::Oblique,
+}
+
+cast_to_value! {
+ v: FontStyle => Value::from(match v {
+ FontStyle::Normal => "normal",
+ FontStyle::Italic => "italic",
+ FontStyle::Oblique => "oblique",
+ })
+}
+
/// The weight of a font.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
@@ -127,6 +148,44 @@ impl Debug for FontWeight {
}
}
+cast_from_value! {
+ FontWeight,
+ v: i64 => Self::from_number(v.clamp(0, u16::MAX as i64) as u16),
+ /// Thin weight (100).
+ "thin" => Self::THIN,
+ /// Extra light weight (200).
+ "extralight" => Self::EXTRALIGHT,
+ /// Light weight (300).
+ "light" => Self::LIGHT,
+ /// Regular weight (400).
+ "regular" => Self::REGULAR,
+ /// Medium weight (500).
+ "medium" => Self::MEDIUM,
+ /// Semibold weight (600).
+ "semibold" => Self::SEMIBOLD,
+ /// Bold weight (700).
+ "bold" => Self::BOLD,
+ /// Extrabold weight (800).
+ "extrabold" => Self::EXTRABOLD,
+ /// Black weight (900).
+ "black" => Self::BLACK,
+}
+
+cast_to_value! {
+ v: FontWeight => Value::from(match v {
+ FontWeight::THIN => "thin",
+ FontWeight::EXTRALIGHT => "extralight",
+ FontWeight::LIGHT => "light",
+ FontWeight::REGULAR => "regular",
+ FontWeight::MEDIUM => "medium",
+ FontWeight::SEMIBOLD => "semibold",
+ FontWeight::BOLD => "bold",
+ FontWeight::EXTRABOLD => "extrabold",
+ FontWeight::BLACK => "black",
+ _ => return v.to_number().into(),
+ })
+}
+
/// The width of a font.
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
#[derive(Serialize, Deserialize)]
@@ -163,8 +222,8 @@ impl FontStretch {
/// Create a font stretch from a ratio between 0.5 and 2.0, clamping it if
/// necessary.
- pub fn from_ratio(ratio: f32) -> Self {
- Self((ratio.max(0.5).min(2.0) * 1000.0) as u16)
+ pub fn from_ratio(ratio: Ratio) -> Self {
+ Self((ratio.get().max(0.5).min(2.0) * 1000.0) as u16)
}
/// Create a font stretch from an OpenType-style number between 1 and 9,
@@ -184,12 +243,12 @@ impl FontStretch {
}
/// The ratio between 0.5 and 2.0 corresponding to this stretch.
- pub fn to_ratio(self) -> f32 {
- self.0 as f32 / 1000.0
+ pub fn to_ratio(self) -> Ratio {
+ Ratio::new(self.0 as f64 / 1000.0)
}
/// The absolute ratio distance between this and another font stretch.
- pub fn distance(self, other: Self) -> f32 {
+ pub fn distance(self, other: Self) -> Ratio {
(self.to_ratio() - other.to_ratio()).abs()
}
}
@@ -202,10 +261,19 @@ impl Default for FontStretch {
impl Debug for FontStretch {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
- write!(f, "{}%", 100.0 * self.to_ratio())
+ self.to_ratio().fmt(f)
}
}
+cast_from_value! {
+ FontStretch,
+ v: Ratio => Self::from_ratio(v),
+}
+
+cast_to_value! {
+ v: FontStretch => v.to_ratio().into()
+}
+
#[cfg(test)]
mod tests {
use super::*;