@@ -56,6 +56,77 @@ pub fn clap_app() -> clap::App<'static, 'static> {
5656 . help ( r#"<f64> Constant stroke width."# )
5757 . validator ( super :: arg_validator_positive_f64)
5858 . required ( true ) )
59+ . arg ( Arg :: with_name ( "remove-internal" )
60+ . long ( "remove-internal" )
61+ . short ( "I" )
62+ . takes_value ( false )
63+ . help ( r#"Remove internal contour"# ) )
64+ . arg ( Arg :: with_name ( "remove-external" )
65+ . long ( "remove-external" )
66+ . short ( "E" )
67+ . takes_value ( false )
68+ . help ( r#"Remove external contour"# ) )
69+ }
70+
71+ #[ derive( Debug ) ]
72+ struct CWSSettings {
73+ vws_settings : VWSSettings ,
74+ width : f64 ,
75+ jointype : JoinType ,
76+ startcap : CapType ,
77+ endcap : CapType ,
78+ remove_internal : bool ,
79+ remove_external : bool ,
80+ }
81+
82+ fn constant_width_stroke (
83+ path : & glifparser:: Glif < Option < PointData > > ,
84+ settings : & CWSSettings ,
85+ ) -> Outline < Option < PointData > > {
86+ let vws_contour = VWSContour {
87+ id : 0 ,
88+ join_type : settings. jointype ,
89+ cap_start_type : settings. startcap ,
90+ cap_end_type : settings. endcap ,
91+ handles : vec ! [ ] , // to be populated based on number of points
92+ remove_internal : settings. remove_internal ,
93+ remove_external : settings. remove_external ,
94+ } ;
95+
96+ // convert our path and pattern to piecewise collections of beziers
97+ let piece_path = Piecewise :: from ( path. outline . as_ref ( ) . unwrap ( ) ) ;
98+ let mut output_outline: Outline < Option < PointData > > = Vec :: new ( ) ;
99+
100+ let mut vws_contours = vec ! [ vws_contour; path. outline. as_ref( ) . unwrap( ) . len( ) ] ;
101+
102+ let vws_handle = VWSHandle {
103+ left_offset : settings. width / 2.0 ,
104+ right_offset : settings. width / 2.0 ,
105+ tangent_offset : 0.0 ,
106+ interpolation : InterpolationType :: Linear ,
107+ } ;
108+
109+ for outline in path. outline . as_ref ( ) {
110+ for ( cidx, contour) in outline. iter ( ) . enumerate ( ) {
111+ let pointiter = contour. iter ( ) . enumerate ( ) ;
112+
113+ for ( _, _) in pointiter {
114+ vws_contours[ cidx] . handles . push ( vws_handle) ;
115+ }
116+ vws_contours[ cidx] . handles . push ( vws_handle) ;
117+ }
118+ }
119+
120+ let iter = piece_path. segs . iter ( ) . enumerate ( ) ;
121+ for ( i, pwpath_contour) in iter {
122+ let vws_contour = & vws_contours[ i] ;
123+
124+ let results = variable_width_stroke ( & pwpath_contour, & vws_contour, & settings. vws_settings ) ;
125+ for result_contour in results. segs {
126+ output_outline. push ( result_contour. to_contour ( ) ) ;
127+ }
128+ }
129+ output_outline
59130}
60131
61132// Constant width stroking is really just a special case of variable width stroking. So, we take
@@ -96,60 +167,36 @@ pub fn cws_cli(matches: &clap::ArgMatches) {
96167 let startcap = str_to_cap ( matches. value_of ( "startcap" ) . unwrap ( ) ) ;
97168 let endcap = str_to_cap ( matches. value_of ( "endcap" ) . unwrap ( ) ) ;
98169 let jointype = str_to_jointype ( matches. value_of ( "jointype" ) . unwrap ( ) ) ;
170+ let remove_internal = matches. is_present ( "remove-internal" ) ;
171+ let remove_external = matches. is_present ( "remove-external" ) ;
99172
100173 let width: f64 = matches. value_of ( "width" ) . unwrap ( ) . parse ( ) . unwrap ( ) ;
101174 let path: glifparser:: Glif < Option < PointData > > =
102175 glifparser:: read_ufo_glif ( & fs:: read_to_string ( input_file) . expect ( "Failed to read file!" ) ) ;
103176
104- let vws_contour = VWSContour {
105- id : 0 ,
106- join_type : jointype,
107- cap_start_type : startcap,
108- cap_end_type : endcap,
109- handles : vec ! [ ] , // to be populated based on number of points
110- } ;
111-
112- let settings = VWSSettings {
177+ let vws_settings = VWSSettings {
113178 cap_custom_end : custom_cap_if_requested ( endcap, matches. value_of ( "endcap" ) . unwrap ( ) ) ,
114179 cap_custom_start : custom_cap_if_requested ( startcap, matches. value_of ( "startcap" ) . unwrap ( ) ) ,
115180 } ;
116181
117- // convert our path and pattern to piecewise collections of beziers
118- let piece_path = Piecewise :: from ( path. outline . as_ref ( ) . unwrap ( ) ) ;
119- let mut output_outline: Outline < Option < PointData > > = Vec :: new ( ) ;
120-
121- let mut vws_contours = vec ! [ vws_contour; path. outline. as_ref( ) . unwrap( ) . len( ) ] ;
122-
123- let vws_handle = VWSHandle {
124- left_offset : width / 2.0 ,
125- right_offset : width / 2.0 ,
126- tangent_offset : 0.0 ,
127- interpolation : InterpolationType :: Linear ,
182+ let cws_settings = CWSSettings {
183+ vws_settings : vws_settings,
184+ width : width,
185+ startcap : startcap,
186+ endcap : endcap,
187+ jointype : jointype,
188+ remove_internal : remove_internal,
189+ remove_external : remove_external,
128190 } ;
129191
130- for outline in path. outline . as_ref ( ) {
131- for ( cidx, contour) in outline. iter ( ) . enumerate ( ) {
132- let pointiter = contour. iter ( ) . enumerate ( ) ;
133-
134- for ( _, _) in pointiter {
135- vws_contours[ cidx] . handles . push ( vws_handle) ;
136- }
137- vws_contours[ cidx] . handles . push ( vws_handle) ;
138- }
139- }
140-
141- let iter = piece_path. segs . iter ( ) . enumerate ( ) ;
142- for ( i, pwpath_contour) in iter {
143- let vws_contour = & vws_contours[ i] ;
144-
145- let results = variable_width_stroke ( & pwpath_contour, & vws_contour, & settings) ;
146- for result_contour in results. segs {
147- output_outline. push ( result_contour. to_contour ( ) ) ;
148- }
149- }
192+ let output_outline = path
193+ . outline
194+ . as_ref ( )
195+ . map ( |_| Some ( constant_width_stroke ( & path, & cws_settings) ) )
196+ . unwrap_or_else ( || None ) ;
150197
151198 let out = Glif {
152- outline : Some ( output_outline) ,
199+ outline : output_outline,
153200 order : path. order ,
154201 anchors : path. anchors . clone ( ) ,
155202 width : path. width ,
@@ -158,6 +205,7 @@ pub fn cws_cli(matches: &clap::ArgMatches) {
158205 format : 2 ,
159206 lib : None ,
160207 } ;
208+
161209 let glifstring = glifparser:: write_ufo_glif ( & out) ;
162210 fs:: write ( output_file, glifstring) . expect ( "Unable to write file" ) ;
163211}
0 commit comments