diffenator3_lib/
setting.rs1use std::fmt::{Display, Formatter};
2
3use skrifa::setting::VariationSetting;
4
5use crate::dfont::DFont;
6
7#[derive(Debug, Clone, PartialEq)]
11pub enum Setting {
12 Instance(String),
13 Location(Vec<VariationSetting>),
14 Default,
15}
16
17impl Eq for Setting {}
18impl std::hash::Hash for Setting {
19 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
20 format!("{:?}", self).hash(state);
21 }
22}
23
24pub fn parse_location(variations: &str) -> Result<Vec<VariationSetting>, String> {
25 let mut settings: Vec<VariationSetting> = vec![];
26 for variation in variations.split(&[',', ' ']) {
27 if variation.is_empty() {
28 continue;
29 }
30 let mut parts = variation.split('=');
31 let axis = parts.next().ok_or("Couldn't parse axis".to_string())?;
32 let value = parts.next().ok_or("Couldn't parse value".to_string())?;
33 let value = value
34 .parse::<f32>()
35 .map_err(|_| "Couldn't parse value".to_string())?;
36 settings.push((axis, value).into());
37 }
38 Ok(settings)
39}
40
41impl Display for Setting {
42 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
43 match self {
44 Setting::Instance(inst) => write!(f, "{} instance", inst),
45 Setting::Location(loc) => {
46 let loc = loc
47 .iter()
48 .map(|vs| format!("{}={}", vs.selector, vs.value))
49 .collect::<Vec<String>>()
50 .join(",");
51 write!(f, "{}", loc)
52 }
53 Setting::Default => write!(f, "default location"),
54 }
55 }
56}
57impl Setting {
58 pub fn from_instance(instance: String) -> Self {
59 Setting::Instance(instance)
60 }
61 pub fn from_setting(location: Vec<VariationSetting>) -> Self {
62 Setting::Location(location)
63 }
64 pub fn set_on_fonts(&self, font_a: &mut DFont, font_b: &mut DFont) -> Result<(), String> {
65 match self {
66 Setting::Instance(inst) => {
67 font_a
68 .set_instance(inst)
69 .map_err(|_e| format!("Old font does not contain instance '{}'", inst))?;
70 font_b
71 .set_instance(inst)
72 .map_err(|_e| format!("New font does not contain instance '{}'", inst))?;
73 }
74 Setting::Location(loc) => {
75 font_a.location = loc.clone();
76 font_a.normalize_location();
77 font_b.location = loc.clone();
78 font_b.normalize_location();
79 }
80 Setting::Default => {}
81 }
82 log::debug!("Font A location is: {:?}", font_a.location);
83 log::debug!("Font B location is: {:?}", font_b.location);
84 log::debug!(
85 "Font A normalized location is: {:?}",
86 font_a.normalized_location
87 );
88 log::debug!(
89 "Font B normalized location is: {:?}",
90 font_b.normalized_location
91 );
92 Ok(())
93 }
94
95 pub fn name(&self) -> String {
96 match self {
97 Setting::Instance(inst) => inst.clone(),
98 Setting::Location(loc) => loc
99 .iter()
100 .map(|vs| format!("{}={}", vs.selector, vs.value))
101 .collect::<Vec<String>>()
102 .join(","),
103 Setting::Default => "Default".to_string(),
104 }
105 }
106}