11use std:: {
22 convert:: TryInto ,
3+ fmt,
34 io:: BufWriter ,
4- num:: TryFromIntError ,
5+ num:: { ParseFloatError , TryFromIntError } ,
56 path:: { Path , PathBuf } ,
7+ str:: FromStr ,
68} ;
79
810use clap:: Parser ;
911use color_eyre:: eyre:: { self , eyre, Context , ContextCompat } ;
12+ use fontdue:: VariationAxis ;
1013use signum:: {
1114 chsets:: {
1215 editor:: { EChar , ESet , ECHAR_NULL } ,
@@ -48,6 +51,63 @@ pub struct Opts {
4851 /// Threshold at which to treat coverage as "on"
4952 #[ clap( short, long, default_value = "170" ) ]
5053 threshold : u8 ,
54+
55+ #[ clap( short, long) ]
56+ variation : Vec < Variation > ,
57+ }
58+
59+ #[ derive( Debug , Copy , Clone ) ]
60+ struct Variation {
61+ axis : VariationAxis ,
62+ value : f32 ,
63+ }
64+
65+ fn variation_tag ( s : & str ) -> Option < VariationAxis > {
66+ if s. is_ascii ( ) && s. len ( ) == 4 {
67+ let mut chars = s. chars ( ) ;
68+ let a = chars. next ( ) ?;
69+ let b = chars. next ( ) ?;
70+ let c = chars. next ( ) ?;
71+ let d = chars. next ( ) ?;
72+ Some ( VariationAxis :: from_bytes ( [
73+ a as u8 , b as u8 , c as u8 , d as u8 ,
74+ ] ) )
75+ } else {
76+ None
77+ }
78+ }
79+
80+ #[ derive( Debug , Clone ) ]
81+ enum VariationError {
82+ NoEquals ,
83+ MalformedTag ,
84+ #[ allow( dead_code) ]
85+ Value ( ParseFloatError ) ,
86+ }
87+
88+ impl From < ParseFloatError > for VariationError {
89+ fn from ( value : ParseFloatError ) -> Self {
90+ Self :: Value ( value)
91+ }
92+ }
93+
94+ impl std:: error:: Error for VariationError { }
95+
96+ impl fmt:: Display for VariationError {
97+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
98+ <Self as fmt:: Debug >:: fmt ( self , f)
99+ }
100+ }
101+
102+ impl FromStr for Variation {
103+ type Err = VariationError ;
104+
105+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
106+ let ( first, rest) = s. split_once ( "=" ) . ok_or ( VariationError :: NoEquals ) ?;
107+ let axis = variation_tag ( first) . ok_or ( VariationError :: MalformedTag ) ?;
108+ let value = f32:: from_str ( rest) ?;
109+ Ok ( Variation { axis, value } )
110+ }
51111}
52112
53113fn main ( ) -> eyre:: Result < ( ) > {
@@ -62,11 +122,13 @@ fn main() -> eyre::Result<()> {
62122 let ligatures = LigatureInfo :: new ( & face) ;
63123
64124 // Parse it into the font type.
65- let font_settings = fontdue:: FontSettings {
66- collection_index : opt. index ,
67- load_substitutions : true ,
68- ..Default :: default ( )
69- } ;
125+ let mut font_settings = fontdue:: FontSettings :: default ( ) ;
126+ font_settings. collection_index = opt. index ;
127+ font_settings. load_substitutions = true ;
128+
129+ for var in & opt. variation {
130+ font_settings. variations . insert ( var. axis , var. value ) ;
131+ }
70132 let font = fontdue:: Font :: from_bytes ( & font[ ..] , font_settings)
71133 . map_err ( |e| eyre ! ( "Failed to load font: {}" , e) ) ?;
72134
0 commit comments