11use crate :: core:: graph:: OverlayGraph ;
2- use crate :: core:: overlay:: ContourDirection ;
3- use crate :: float:: filter:: ContourFilter ;
2+ use crate :: float:: overlay:: OverlayOptions ;
43use crate :: float:: source:: resource:: OverlayResource ;
54use crate :: mesh:: stroke:: builder:: StrokeBuilder ;
65use crate :: mesh:: style:: StrokeStyle ;
@@ -10,6 +9,7 @@ use i_float::float::number::FloatNumber;
109use i_float:: float:: rect:: FloatRect ;
1110use i_shape:: base:: data:: Shapes ;
1211use i_shape:: float:: adapter:: ShapesToFloat ;
12+ use i_shape:: float:: despike:: DeSpikeContour ;
1313use i_shape:: float:: simple:: SimplifyContour ;
1414
1515pub trait StrokeOffset < P : FloatPointCompatible < T > , T : FloatNumber > {
@@ -28,10 +28,7 @@ pub trait StrokeOffset<P: FloatPointCompatible<T>, T: FloatNumber> {
2828 ///
2929 /// - `style`: Defines the stroke properties, including width, line caps, and joins.
3030 /// - `is_closed_path`: Specifies whether the path is closed (true) or open (false).
31- /// - `main_direction`: Winding direction for the **output** main (outer) contour. All hole contours will automatically use the opposite direction. Impact on **output** only!
32- /// - `filter`: Defines optional contour filtering and simplification:
33- /// - `min_area`: Retains only contours with an area larger than this value.
34- /// - `simplify`: If `true`, simplifies contours and removes degenerate edges.
31+ /// - `options`: Adjust custom behavior.
3532 ///
3633 /// # Returns
3734 /// A collection of `Shapes<P>` representing the stroke geometry.
@@ -41,8 +38,7 @@ pub trait StrokeOffset<P: FloatPointCompatible<T>, T: FloatNumber> {
4138 & self ,
4239 style : StrokeStyle < P , T > ,
4340 is_closed_path : bool ,
44- main_direction : ContourDirection ,
45- filter : ContourFilter < T > ,
41+ options : OverlayOptions < T > ,
4642 ) -> Shapes < P > ;
4743}
4844
@@ -53,20 +49,14 @@ where
5349 T : FloatNumber + ' static ,
5450{
5551 fn stroke ( & self , style : StrokeStyle < P , T > , is_closed_path : bool ) -> Shapes < P > {
56- self . stroke_custom (
57- style,
58- is_closed_path,
59- ContourDirection :: CounterClockwise ,
60- Default :: default ( ) ,
61- )
52+ self . stroke_custom ( style, is_closed_path, Default :: default ( ) )
6253 }
6354
6455 fn stroke_custom (
6556 & self ,
6657 style : StrokeStyle < P , T > ,
6758 is_closed_path : bool ,
68- main_direction : ContourDirection ,
69- filter : ContourFilter < T > ,
59+ options : OverlayOptions < T > ,
7060 ) -> Shapes < P > {
7161 let mut paths_count = 0 ;
7262 let mut points_count = 0 ;
@@ -101,13 +91,18 @@ where
10191 builder. build ( path, is_closed_path, & adapter, & mut segments) ;
10292 }
10393
94+ let min_area = adapter. sqr_float_to_int ( options. min_output_area ) ;
10495 let shapes = OverlayGraph :: offset_graph_with_solver ( segments, Default :: default ( ) )
105- . extract_offset ( main_direction , 0 ) ;
96+ . extract_offset ( options . output_direction , min_area ) ;
10697
10798 let mut float = shapes. to_float ( & adapter) ;
10899
109- if filter. clean_result {
110- float. simplify_contour ( & adapter) ;
100+ if options. clean_result {
101+ if options. preserve_output_collinear {
102+ float. despike_contour ( & adapter) ;
103+ } else {
104+ float. simplify_contour ( & adapter) ;
105+ }
111106 } ;
112107
113108 float
@@ -116,7 +111,6 @@ where
116111
117112#[ cfg( test) ]
118113mod tests {
119- use crate :: core:: overlay:: ContourDirection ;
120114 use crate :: mesh:: stroke:: offset:: StrokeOffset ;
121115 use crate :: mesh:: style:: { LineCap , LineJoin , StrokeStyle } ;
122116 use std:: f32:: consts:: PI ;
@@ -205,12 +199,7 @@ mod tests {
205199
206200 let style = StrokeStyle :: new ( 2.0 ) ;
207201
208- let shapes = path. stroke_custom (
209- style,
210- true ,
211- ContourDirection :: CounterClockwise ,
212- Default :: default ( ) ,
213- ) ;
202+ let shapes = path. stroke_custom ( style, true , Default :: default ( ) ) ;
214203 assert_eq ! ( shapes. len( ) , 1 ) ;
215204
216205 let shape = shapes. first ( ) . unwrap ( ) ;
@@ -232,12 +221,7 @@ mod tests {
232221
233222 let style = StrokeStyle :: new ( 10.0 ) . line_join ( LineJoin :: Miter ( 0.1 ) ) ;
234223
235- let shapes = path. stroke_custom (
236- style,
237- false ,
238- ContourDirection :: CounterClockwise ,
239- Default :: default ( ) ,
240- ) ;
224+ let shapes = path. stroke_custom ( style, false , Default :: default ( ) ) ;
241225 assert_eq ! ( shapes. len( ) , 1 ) ;
242226
243227 let shape = shapes. first ( ) . unwrap ( ) ;
@@ -250,12 +234,7 @@ mod tests {
250234
251235 let style = StrokeStyle :: new ( 10.0 ) . line_join ( LineJoin :: Miter ( 0.1 ) ) ;
252236
253- let shapes = path. stroke_custom (
254- style,
255- false ,
256- ContourDirection :: CounterClockwise ,
257- Default :: default ( ) ,
258- ) ;
237+ let shapes = path. stroke_custom ( style, false , Default :: default ( ) ) ;
259238 assert_eq ! ( shapes. len( ) , 1 ) ;
260239
261240 let shape = shapes. first ( ) . unwrap ( ) ;
0 commit comments