@@ -188,35 +188,43 @@ impl<I0: Iterator + Clone, Size: SizeDesc, DB: DrawingBackend> Drawable<DB>
188188 None => return Ok ( ( ) ) ,
189189 } ;
190190 let size = self . size . in_pixels ( & ps) . max ( 0 ) as f32 ;
191+ if size == 0. {
192+ return Ok ( ( ) ) ;
193+ }
191194 let spacing = self . spacing . in_pixels ( & ps) . max ( 0 ) as f32 ;
192195 let mut dist = 0. ;
193196 let mut is_solid = true ;
194197 let mut queue = vec ! [ to_i( start) ] ;
195198 for curr in points {
196- let curr_f = to_f ( curr) ;
197- let ( dx , dy ) = ( curr_f . 0 - start . 0 , curr_f . 1 - start . 1 ) ;
198- let d = dx . hypot ( dy ) . max ( f32 :: EPSILON ) ;
199- dist += d ;
200- if is_solid {
201- if dist < size {
202- queue . push ( curr ) ;
203- start = curr_f ;
204- } else {
205- let t = ( dist - size ) / d;
199+ let end = to_f ( curr) ;
200+ // Loop for solid and spacing
201+ while start != end {
202+ let ( dx , dy ) = ( end . 0 - start . 0 , end . 1 - start . 1 ) ;
203+ let d = dx . hypot ( dy ) ;
204+ let size = if is_solid { size } else { spacing } ;
205+ let left = size - dist ;
206+ // Set next point to `start`
207+ if left < d {
208+ let t = left / d;
206209 start = ( start. 0 + dx * t, start. 1 + dy * t) ;
210+ dist += left;
211+ } else {
212+ start = end;
213+ dist += d;
214+ }
215+ // Draw if needed
216+ if is_solid {
207217 queue. push ( to_i ( start) ) ;
208- backend. draw_path ( queue. drain ( ..) , & self . style ) ?;
218+ }
219+ if size <= dist {
220+ if is_solid {
221+ backend. draw_path ( queue. drain ( ..) , & self . style ) ?;
222+ } else {
223+ queue. push ( to_i ( start) ) ;
224+ }
209225 dist = 0. ;
210- is_solid = false ;
226+ is_solid = !is_solid ;
211227 }
212- } else if dist < spacing {
213- start = curr_f;
214- } else {
215- let t = ( dist - spacing) / d;
216- start = ( start. 0 + dx * t, start. 1 + dy * t) ;
217- queue. push ( to_i ( start) ) ;
218- dist = 0. ;
219- is_solid = true ;
220228 }
221229 }
222230 if queue. len ( ) > 1 {
@@ -231,9 +239,9 @@ impl<I0: Iterator + Clone, Size: SizeDesc, DB: DrawingBackend> Drawable<DB>
231239fn test_dashed_path_element ( ) {
232240 use crate :: prelude:: * ;
233241 let check_list = std:: cell:: RefCell :: new ( vec ! [
234- vec![ ( 100 , 100 ) , ( 100 , 103 ) , ( 100 , 118 ) ] ,
235- vec![ ( 100 , 105 ) , ( 100 , 110 ) ] ,
236- vec![ ( 100 , 112 ) , ( 100 , 117 ) ] ,
242+ vec![ ( 100 , 100 ) , ( 100 , 103 ) , ( 100 , 105 ) ] ,
243+ vec![ ( 100 , 107 ) , ( 100 , 112 ) ] ,
244+ vec![ ( 100 , 114 ) , ( 100 , 119 ) ] ,
237245 vec![ ( 100 , 119 ) , ( 100 , 120 ) ] ,
238246 ] ) ;
239247 let da = crate :: create_mocked_drawing_area ( 300 , 300 , |m| {
@@ -243,8 +251,8 @@ fn test_dashed_path_element() {
243251 assert_eq ! ( path, check_list. borrow_mut( ) . remove( 0 ) ) ;
244252 } ) ;
245253 m. drop_check ( |b| {
246- assert_eq ! ( b. num_draw_path_call, 1 ) ;
247- assert_eq ! ( b. draw_count, 1 ) ;
254+ assert_eq ! ( b. num_draw_path_call, 3 ) ;
255+ assert_eq ! ( b. draw_count, 3 ) ;
248256 } ) ;
249257 } ) ;
250258 da. draw ( & DashedPathElement :: new (
0 commit comments