1use crate::fill::{compare_positions, is_after};
2use crate::geom::{CubicBezierSegment, LineSegment, QuadraticBezierSegment};
3use crate::math::{point, Point};
4use crate::path::private::DebugValidator;
5use crate::path::{EndpointId, IdEvent, PathEvent, PositionStore};
6use crate::Orientation;
7
8use core::cmp::Ordering;
9use core::mem::swap;
10use core::ops::Range;
11use alloc::vec::Vec;
12
13#[inline]
14fn reorient(p: Point) -> Point {
15 point(-p.y, p.x)
16}
17
18pub(crate) type TessEventId = u32;
19
20pub(crate) const INVALID_EVENT_ID: TessEventId = u32::MAX;
21
22pub(crate) struct Event {
23 pub next_sibling: TessEventId,
24 pub next_event: TessEventId,
25 pub position: Point,
26}
27
28#[derive(Clone, Debug)]
29pub(crate) struct EdgeData {
30 pub to: Point,
31 pub range: core::ops::Range<f32>,
32 pub winding: i16,
33 pub is_edge: bool,
34 pub from_id: EndpointId,
35 pub to_id: EndpointId,
36}
37
38#[doc(hidden)]
39pub struct EventQueue {
41 pub(crate) events: Vec<Event>,
42 pub(crate) edge_data: Vec<EdgeData>,
43 first: TessEventId,
44 sorted: bool,
45}
46
47impl Default for EventQueue {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53impl EventQueue {
54 pub fn new() -> Self {
55 EventQueue {
56 events: Vec::new(),
57 edge_data: Vec::new(),
58 first: INVALID_EVENT_ID,
59 sorted: false,
60 }
61 }
62
63 pub fn with_capacity(cap: usize) -> Self {
64 EventQueue {
65 events: Vec::with_capacity(cap),
66 edge_data: Vec::with_capacity(cap),
67 first: INVALID_EVENT_ID,
68 sorted: false,
69 }
70 }
71
72 pub fn reset(&mut self) {
73 self.events.clear();
74 self.edge_data.clear();
75 self.first = INVALID_EVENT_ID;
76 self.sorted = false;
77 }
78
79 pub fn from_path(tolerance: f32, path: impl IntoIterator<Item = PathEvent>) -> Self {
85 let path = path.into_iter();
86 let (min, max) = path.size_hint();
87 let capacity = max.unwrap_or(min);
88 let mut builder = EventQueueBuilder::with_capacity(capacity, tolerance);
89 builder.set_path(tolerance, Orientation::Vertical, path);
90
91 builder.build()
92 }
93
94 pub fn from_path_with_ids(
102 tolerance: f32,
103 sweep_orientation: Orientation,
104 path: impl IntoIterator<Item = IdEvent>,
105 positions: &impl PositionStore,
106 ) -> Self {
107 let path = path.into_iter();
108 let (min, max) = path.size_hint();
109 let capacity = max.unwrap_or(min);
110 let mut builder = EventQueueBuilder::with_capacity(capacity, tolerance);
111 builder.set_path_with_ids(tolerance, sweep_orientation, path, positions);
112
113 builder.build()
114 }
115
116 pub fn into_builder(mut self, tolerance: f32) -> EventQueueBuilder {
117 self.reset();
118 EventQueueBuilder {
119 queue: self,
120 current: point(f32::NAN, f32::NAN),
121 prev: point(f32::NAN, f32::NAN),
122 second: point(f32::NAN, f32::NAN),
123 nth: 0,
124 tolerance,
125 prev_endpoint_id: EndpointId(u32::MAX),
126 validator: DebugValidator::new(),
127 }
128 }
129
130 pub fn reserve(&mut self, n: usize) {
131 self.events.reserve(n);
132 }
133
134 fn push_unsorted(&mut self, position: Point) {
135 self.events.push(Event {
136 position,
137 next_sibling: INVALID_EVENT_ID,
138 next_event: INVALID_EVENT_ID,
139 });
140 }
141
142 fn push_sorted(&mut self, position: Point) {
143 self.events.push(Event {
144 position,
145 next_sibling: u32::MAX,
146 next_event: u32::MAX,
147 });
148
149 let id = (self.events.len() - 1) as u32;
150 let mut current = self.first_id();
151 let mut prev = current;
152 while self.valid_id(current) {
153 let evt_pos = self.events[current as usize].position;
154 match compare_positions(position, evt_pos) {
155 Ordering::Greater => {}
156 Ordering::Equal => {
157 let mut current_sibling = current;
159 let mut next_sibling = self.next_sibling_id(current);
160 while self.valid_id(next_sibling) {
161 current_sibling = next_sibling;
162 next_sibling = self.next_sibling_id(current_sibling);
163 }
164 self.events[current_sibling as usize].next_sibling = id;
165 return;
166 }
167 Ordering::Less => {
168 if prev != current {
169 self.events[prev as usize].next_event = id;
171 } else {
172 self.first = id;
174 }
175 self.events[id as usize].next_event = current;
176 return;
177 }
178 }
179
180 prev = current;
181 current = self.next_id(current);
182 }
183
184 self.events[prev as usize].next_event = id;
186 }
187
188 pub(crate) fn insert_sorted(
189 &mut self,
190 position: Point,
191 data: EdgeData,
192 after: TessEventId,
193 ) -> TessEventId {
194 debug_assert!(self.sorted);
195 debug_assert!(
196 is_after(data.to, position),
197 "{:?} should be after {:?}",
198 data.to,
199 position
200 );
201
202 let idx = self.events.len() as TessEventId;
203 self.events.push(Event {
204 position,
205 next_sibling: INVALID_EVENT_ID,
206 next_event: INVALID_EVENT_ID,
207 });
208 self.edge_data.push(data);
209
210 self.insert_into_sorted_list(idx, position, after);
211
212 idx
213 }
214
215 pub(crate) fn insert_sibling(&mut self, sibling: TessEventId, position: Point, data: EdgeData) {
216 debug_assert!(is_after(data.to, position));
217 let idx = self.events.len() as TessEventId;
218 let next_sibling = self.events[sibling as usize].next_sibling;
219
220 self.events.push(Event {
221 position,
222 next_event: INVALID_EVENT_ID,
223 next_sibling,
224 });
225
226 self.edge_data.push(data);
227
228 self.events[sibling as usize].next_sibling = idx;
229 }
230
231 pub(crate) fn vertex_event_sorted(
232 &mut self,
233 position: Point,
234 endpoint_id: EndpointId,
235 after: TessEventId,
236 ) {
237 let idx = self.events.len() as TessEventId;
238
239 self.push_unsorted(position);
240 self.edge_data.push(EdgeData {
241 to: point(f32::NAN, f32::NAN),
242 range: 0.0..0.0,
243 winding: 0,
244 is_edge: false,
245 from_id: endpoint_id,
246 to_id: endpoint_id,
247 });
248
249 self.insert_into_sorted_list(idx, position, after);
250 }
251
252 fn insert_into_sorted_list(&mut self, idx: TessEventId, position: Point, after: TessEventId) {
253 let mut prev = after;
254 let mut current = after;
255 while self.valid_id(current) {
256 let pos = self.events[current as usize].position;
257
258 if pos == position {
259 debug_assert!(prev != current);
260 self.events[idx as usize].next_sibling = self.events[current as usize].next_sibling;
261 self.events[current as usize].next_sibling = idx;
262 return;
263 } else if is_after(pos, position) {
264 self.events[prev as usize].next_event = idx;
265 self.events[idx as usize].next_event = current;
266 return;
267 }
268
269 prev = current;
270 current = self.next_id(current);
271 }
272
273 self.events[prev as usize].next_event = idx;
274 }
275
276 pub(crate) fn first_id(&self) -> TessEventId {
278 self.first
279 }
280
281 pub(crate) fn next_id(&self, id: TessEventId) -> TessEventId {
283 self.events[id as usize].next_event
284 }
285
286 pub(crate) fn next_sibling_id(&self, id: TessEventId) -> TessEventId {
288 self.events[id as usize].next_sibling
289 }
290
291 pub(crate) fn valid_id(&self, id: TessEventId) -> bool {
293 id != INVALID_EVENT_ID
294 }
295
296 pub(crate) fn position(&self, id: TessEventId) -> Point {
298 self.events[id as usize].position
299 }
300
301 fn sort(&mut self) {
302 self.sorted = true;
303
304 if self.events.is_empty() {
305 return;
306 }
307
308 let range = 0..self.events.len();
309 self.first = self.merge_sort(range);
310 }
311
312 fn merge_sort(&mut self, range: Range<usize>) -> TessEventId {
318 let split = (range.start + range.end) / 2;
319
320 if split == range.start {
321 return range.start as TessEventId;
322 }
323
324 let a_head = self.merge_sort(range.start..split);
325 let b_head = self.merge_sort(split..range.end);
326
327 self.merge(a_head, b_head)
328 }
329
330 fn merge(&mut self, mut a: TessEventId, mut b: TessEventId) -> TessEventId {
331 if a == INVALID_EVENT_ID {
332 return b;
333 }
334 if b == INVALID_EVENT_ID {
335 return a;
336 }
337
338 debug_assert!(a != b);
339 let mut first = true;
340 let mut sorted_head = INVALID_EVENT_ID;
341 let mut prev = INVALID_EVENT_ID;
342
343 loop {
344 if a == INVALID_EVENT_ID {
345 if !first {
346 self.events[prev as usize].next_event = b;
347 }
348 break;
349 }
350
351 if b == INVALID_EVENT_ID {
352 if !first {
353 self.events[prev as usize].next_event = a;
354 }
355 break;
356 }
357
358 let node;
359 match compare_positions(
360 self.events[a as usize].position,
361 self.events[b as usize].position,
362 ) {
363 Ordering::Less => {
364 node = a;
365 a = self.events[a as usize].next_event;
366 }
367 Ordering::Greater => {
368 node = b;
369 b = self.events[b as usize].next_event;
370 }
371 Ordering::Equal => {
372 let a_sib = self.find_last_sibling(a) as usize;
374 self.events[a_sib].next_sibling = b;
375
376 b = self.events[b as usize].next_event;
377
378 continue;
379 }
380 }
381
382 if first {
383 first = false;
384 sorted_head = node;
385 } else {
386 self.events[prev as usize].next_event = node;
387 }
388
389 prev = node;
390 }
391
392 if sorted_head == INVALID_EVENT_ID {
393 sorted_head = a;
394 }
395
396 sorted_head
397 }
398
399 fn find_last_sibling(&self, id: TessEventId) -> TessEventId {
400 let mut current_sibling = id;
401 let mut next_sibling = self.next_sibling_id(id);
402 while self.valid_id(next_sibling) {
403 current_sibling = next_sibling;
404 next_sibling = self.next_sibling_id(current_sibling);
405 }
406
407 current_sibling
408 }
409
410 #[cfg(all(debug_assertions, feature = "std"))]
411 fn log(&self) {
412 let mut iter_count = self.events.len() * self.events.len();
413
414 std::println!("--");
415 let mut current = self.first;
416 while (current as usize) < self.events.len() {
417 assert!(iter_count > 0);
418 iter_count -= 1;
419
420 std::print!("[");
421 let mut current_sibling = current;
422 while (current_sibling as usize) < self.events.len() {
423 std::print!("{:?},", self.events[current_sibling as usize].position);
424 current_sibling = self.events[current_sibling as usize].next_sibling;
425 }
426 std::print!("] ");
427 current = self.events[current as usize].next_event;
428 }
429 std::println!("\n--");
430 }
431
432 fn assert_sorted(&self) {
433 let mut current = self.first;
434 let mut pos = point(f32::MIN, f32::MIN);
435 let mut n = 0;
436 while self.valid_id(current) {
437 assert!(is_after(self.events[current as usize].position, pos));
438 pos = self.events[current as usize].position;
439 let mut current_sibling = current;
440 while self.valid_id(current_sibling) {
441 n += 1;
442 assert_eq!(self.events[current_sibling as usize].position, pos);
443 current_sibling = self.next_sibling_id(current_sibling);
444 }
445 current = self.next_id(current);
446 }
447 assert_eq!(n, self.events.len());
448 }
449}
450
451pub struct EventQueueBuilder {
452 current: Point,
453 prev: Point,
454 second: Point,
455 nth: u32,
456 queue: EventQueue,
457 tolerance: f32,
458 prev_endpoint_id: EndpointId,
459 validator: DebugValidator,
460}
461
462impl EventQueueBuilder {
463 pub fn new(tolerance: f32) -> Self {
464 EventQueue::new().into_builder(tolerance)
465 }
466
467 pub fn with_capacity(cap: usize, tolerance: f32) -> Self {
468 EventQueue::with_capacity(cap).into_builder(tolerance)
469 }
470
471 pub fn set_tolerance(&mut self, tolerance: f32) {
472 self.tolerance = tolerance;
473 }
474
475 pub fn build(mut self) -> EventQueue {
476 self.validator.build();
477
478 self.queue.sort();
479
480 self.queue
481 }
482
483 pub fn set_path(
484 &mut self,
485 tolerance: f32,
486 sweep_orientation: Orientation,
487 path: impl IntoIterator<Item = PathEvent>,
488 ) {
489 self.reset();
490
491 self.tolerance = tolerance;
492 let endpoint_id = EndpointId(u32::MAX);
493 match sweep_orientation {
494 Orientation::Vertical => {
495 for evt in path {
496 match evt {
497 PathEvent::Begin { at } => {
498 self.begin(at, endpoint_id);
499 }
500 PathEvent::Line { to, .. } => {
501 self.line_segment(to, endpoint_id, 0.0, 1.0);
502 }
503 PathEvent::Quadratic { ctrl, to, .. } => {
504 self.quadratic_bezier_segment(ctrl, to, endpoint_id);
505 }
506 PathEvent::Cubic {
507 ctrl1, ctrl2, to, ..
508 } => {
509 self.cubic_bezier_segment(ctrl1, ctrl2, to, endpoint_id);
510 }
511 PathEvent::End { first, .. } => {
512 self.end(first, endpoint_id);
513 }
514 }
515 }
516 }
517
518 Orientation::Horizontal => {
519 for evt in path {
520 match evt {
521 PathEvent::Begin { at } => {
522 self.begin(reorient(at), endpoint_id);
523 }
524 PathEvent::Line { to, .. } => {
525 self.line_segment(reorient(to), endpoint_id, 0.0, 1.0);
526 }
527 PathEvent::Quadratic { ctrl, to, .. } => {
528 self.quadratic_bezier_segment(
529 reorient(ctrl),
530 reorient(to),
531 endpoint_id,
532 );
533 }
534 PathEvent::Cubic {
535 ctrl1, ctrl2, to, ..
536 } => {
537 self.cubic_bezier_segment(
538 reorient(ctrl1),
539 reorient(ctrl2),
540 reorient(to),
541 endpoint_id,
542 );
543 }
544 PathEvent::End { first, .. } => {
545 self.end(reorient(first), endpoint_id);
546 }
547 }
548 }
549 }
550 }
551 }
552
553 pub fn set_path_with_ids(
554 &mut self,
555 tolerance: f32,
556 sweep_orientation: Orientation,
557 path_events: impl IntoIterator<Item = IdEvent>,
558 points: &impl PositionStore,
559 ) {
560 self.reset();
561
562 self.tolerance = tolerance;
563 match sweep_orientation {
564 Orientation::Vertical => {
565 for evt in path_events {
566 match evt {
567 IdEvent::Begin { at } => {
568 self.begin(points.get_endpoint(at), at);
569 }
570 IdEvent::Line { to, .. } => {
571 self.line_segment(points.get_endpoint(to), to, 0.0, 1.0);
572 }
573 IdEvent::Quadratic { ctrl, to, .. } => {
574 self.quadratic_bezier_segment(
575 points.get_control_point(ctrl),
576 points.get_endpoint(to),
577 to,
578 );
579 }
580 IdEvent::Cubic {
581 ctrl1, ctrl2, to, ..
582 } => {
583 self.cubic_bezier_segment(
584 points.get_control_point(ctrl1),
585 points.get_control_point(ctrl2),
586 points.get_endpoint(to),
587 to,
588 );
589 }
590 IdEvent::End { first, .. } => {
591 self.end(points.get_endpoint(first), first);
592 }
593 }
594 }
595 }
596
597 Orientation::Horizontal => {
598 for evt in path_events {
599 match evt {
600 IdEvent::Begin { at } => {
601 self.begin(reorient(points.get_endpoint(at)), at);
602 }
603 IdEvent::Line { to, .. } => {
604 self.line_segment(reorient(points.get_endpoint(to)), to, 0.0, 1.0);
605 }
606 IdEvent::Quadratic { ctrl, to, .. } => {
607 self.quadratic_bezier_segment(
608 reorient(points.get_control_point(ctrl)),
609 reorient(points.get_endpoint(to)),
610 to,
611 );
612 }
613 IdEvent::Cubic {
614 ctrl1, ctrl2, to, ..
615 } => {
616 self.cubic_bezier_segment(
617 reorient(points.get_control_point(ctrl1)),
618 reorient(points.get_control_point(ctrl2)),
619 reorient(points.get_endpoint(to)),
620 to,
621 );
622 }
623 IdEvent::End { first, .. } => {
624 self.end(reorient(points.get_endpoint(first)), first);
625 }
626 }
627 }
628 }
629 }
630 }
631
632 fn reset(&mut self) {
633 self.queue.reset();
634 self.nth = 0;
635 }
636
637 fn vertex_event(&mut self, at: Point, endpoint_id: EndpointId) {
638 self.queue.push_unsorted(at);
639 self.queue.edge_data.push(EdgeData {
640 to: point(f32::NAN, f32::NAN),
641 range: 0.0..0.0,
642 winding: 0,
643 is_edge: false,
644 from_id: endpoint_id,
645 to_id: endpoint_id,
646 });
647 }
648
649 fn vertex_event_on_curve(&mut self, at: Point, t: f32, from_id: EndpointId, to_id: EndpointId) {
650 self.queue.push_unsorted(at);
651 self.queue.edge_data.push(EdgeData {
652 to: point(f32::NAN, f32::NAN),
653 range: t..t,
654 winding: 0,
655 is_edge: false,
656 from_id,
657 to_id,
658 });
659 }
660
661 pub fn end(&mut self, first: Point, first_endpoint_id: EndpointId) {
662 if self.nth == 0 {
663 self.validator.end();
664 return;
665 }
666
667 self.line_segment(first, first_endpoint_id, 0.0, 1.0);
670
671 if is_after(first, self.prev) && is_after(first, self.second) {
675 self.vertex_event(first, first_endpoint_id);
676 }
677
678 self.validator.end();
679
680 self.prev_endpoint_id = first_endpoint_id;
681 self.nth = 0;
682 }
683
684 pub fn begin(&mut self, to: Point, to_id: EndpointId) {
685 self.validator.begin();
686
687 self.nth = 0;
688 self.current = to;
689 self.prev_endpoint_id = to_id;
690 }
691
692 #[allow(clippy::too_many_arguments)]
693 fn add_edge(
694 &mut self,
695 edge: &LineSegment<f32>,
696 mut winding: i16,
697 from_id: EndpointId,
698 to_id: EndpointId,
699 mut t0: f32,
700 mut t1: f32,
701 ) {
702 if edge.from == edge.to {
703 return;
704 }
705
706 let mut evt_pos = edge.from;
707 let mut evt_to = edge.to;
708 if is_after(evt_pos, edge.to) {
709 evt_to = evt_pos;
710 evt_pos = edge.to;
711 swap(&mut t0, &mut t1);
712 winding *= -1;
713 }
714
715 self.queue.push_unsorted(evt_pos);
716 self.queue.edge_data.push(EdgeData {
717 to: evt_to,
718 range: t0..t1,
719 winding,
720 is_edge: true,
721 from_id,
722 to_id,
723 });
724
725 self.nth += 1;
726 }
727
728 pub fn line_segment(&mut self, to: Point, to_id: EndpointId, t0: f32, t1: f32) {
729 self.validator.edge();
730
731 let from = self.current;
732 if from == to {
733 return;
734 }
735
736 if is_after(from, to) && self.nth > 0 && is_after(from, self.prev) {
737 self.vertex_event(from, self.prev_endpoint_id);
738 }
739
740 if self.nth == 0 {
741 self.second = to;
742 }
743
744 self.add_edge(
745 &LineSegment { from, to },
746 1,
747 self.prev_endpoint_id,
748 to_id,
749 t0,
750 t1,
751 );
752
753 self.prev = self.current;
754 self.prev_endpoint_id = to_id;
755 self.current = to;
756 }
757
758 pub fn quadratic_bezier_segment(&mut self, ctrl: Point, to: Point, to_id: EndpointId) {
759 self.validator.edge();
760 let original = QuadraticBezierSegment {
768 from: self.current,
769 ctrl,
770 to,
771 };
772
773 let needs_swap = is_after(original.from, original.to);
774
775 let mut segment = original;
776 let mut winding = 1;
777 if needs_swap {
778 swap(&mut segment.from, &mut segment.to);
779 winding = -1;
780 }
781
782 let mut prev = segment.from;
783 let mut first = None;
784 let is_first_edge = self.nth == 0;
785 segment.for_each_flattened_with_t(self.tolerance, &mut |line, t| {
786 if line.from == line.to {
787 return;
788 }
789
790 if first.is_none() {
791 first = Some(line.to)
792 } else if is_after(line.from, line.to) && is_after(line.from, prev) {
797 self.vertex_event_on_curve(line.from, t.start, self.prev_endpoint_id, to_id);
798 }
799
800 self.add_edge(line, winding, self.prev_endpoint_id, to_id, t.start, t.end);
801
802 prev = line.from;
803 });
804
805 if let Some(first) = first {
806 let (second, previous) = if needs_swap {
807 (prev, first)
808 } else {
809 (first, prev)
810 };
811
812 if is_first_edge {
813 self.second = second;
814 } else if is_after(original.from, self.prev) && is_after(original.from, second) {
815 self.vertex_event(original.from, self.prev_endpoint_id);
818 }
819
820 self.prev = previous;
821 self.current = original.to;
822 self.prev_endpoint_id = to_id;
823 }
824 }
825
826 pub fn cubic_bezier_segment(
827 &mut self,
828 ctrl1: Point,
829 ctrl2: Point,
830 to: Point,
831 to_id: EndpointId,
832 ) {
833 self.validator.edge();
834 let original = CubicBezierSegment {
842 from: self.current,
843 ctrl1,
844 ctrl2,
845 to,
846 };
847
848 let needs_swap = is_after(original.from, original.to);
849
850 let mut segment = original;
851 let mut winding = 1;
852 if needs_swap {
853 swap(&mut segment.from, &mut segment.to);
854 swap(&mut segment.ctrl1, &mut segment.ctrl2);
855 winding = -1;
856 }
857
858 let mut prev = segment.from;
859 let mut first = None;
860 let is_first_edge = self.nth == 0;
861 segment.for_each_flattened_with_t(self.tolerance, &mut |line, t| {
862 if line.from == line.to {
863 return;
864 }
865
866 if first.is_none() {
867 first = Some(line.to)
868 } else if is_after(line.from, line.to) && is_after(line.from, prev) {
873 self.vertex_event_on_curve(line.from, t.start, self.prev_endpoint_id, to_id);
874 }
875
876 self.add_edge(line, winding, self.prev_endpoint_id, to_id, t.start, t.end);
877
878 prev = line.from;
879 });
880
881 if let Some(first) = first {
882 let (second, previous) = if needs_swap {
883 (prev, first)
884 } else {
885 (first, prev)
886 };
887
888 if is_first_edge {
889 self.second = second;
890 } else if is_after(original.from, self.prev) && is_after(original.from, second) {
891 self.vertex_event(original.from, self.prev_endpoint_id);
894 }
895
896 self.prev = previous;
897 self.current = original.to;
898 self.prev_endpoint_id = to_id;
899 }
900 }
901
902 pub fn reserve(&mut self, n: usize) {
903 self.queue.reserve(n);
904 }
905}
906
907#[test]
908fn test_event_queue_sort_1() {
909 let mut queue = EventQueue::new();
910 queue.push_unsorted(point(0.0, 0.0));
911 queue.push_unsorted(point(4.0, 0.0));
912 queue.push_unsorted(point(2.0, 0.0));
913 queue.push_unsorted(point(3.0, 0.0));
914 queue.push_unsorted(point(4.0, 0.0));
915 queue.push_unsorted(point(0.0, 0.0));
916 queue.push_unsorted(point(6.0, 0.0));
917
918 queue.sort();
919 queue.assert_sorted();
920}
921
922#[test]
923fn test_event_queue_sort_2() {
924 let mut queue = EventQueue::new();
925 queue.push_unsorted(point(0.0, 0.0));
926 queue.push_unsorted(point(0.0, 0.0));
927 queue.push_unsorted(point(0.0, 0.0));
928 queue.push_unsorted(point(0.0, 0.0));
929
930 queue.sort();
931 queue.assert_sorted();
932}
933
934#[test]
935fn test_event_queue_sort_3() {
936 let mut queue = EventQueue::new();
937 queue.push_unsorted(point(0.0, 0.0));
938 queue.push_unsorted(point(1.0, 0.0));
939 queue.push_unsorted(point(2.0, 0.0));
940 queue.push_unsorted(point(3.0, 0.0));
941 queue.push_unsorted(point(4.0, 0.0));
942 queue.push_unsorted(point(5.0, 0.0));
943
944 queue.sort();
945 queue.assert_sorted();
946}
947
948#[test]
949fn test_event_queue_sort_4() {
950 let mut queue = EventQueue::new();
951 queue.push_unsorted(point(5.0, 0.0));
952 queue.push_unsorted(point(4.0, 0.0));
953 queue.push_unsorted(point(3.0, 0.0));
954 queue.push_unsorted(point(2.0, 0.0));
955 queue.push_unsorted(point(1.0, 0.0));
956 queue.push_unsorted(point(0.0, 0.0));
957
958 queue.sort();
959 queue.assert_sorted();
960}
961
962#[test]
963fn test_event_queue_sort_5() {
964 let mut queue = EventQueue::new();
965 queue.push_unsorted(point(5.0, 0.0));
966 queue.push_unsorted(point(5.0, 0.0));
967 queue.push_unsorted(point(4.0, 0.0));
968 queue.push_unsorted(point(4.0, 0.0));
969 queue.push_unsorted(point(3.0, 0.0));
970 queue.push_unsorted(point(3.0, 0.0));
971 queue.push_unsorted(point(2.0, 0.0));
972 queue.push_unsorted(point(2.0, 0.0));
973 queue.push_unsorted(point(1.0, 0.0));
974 queue.push_unsorted(point(1.0, 0.0));
975 queue.push_unsorted(point(0.0, 0.0));
976 queue.push_unsorted(point(0.0, 0.0));
977
978 queue.sort();
979 queue.assert_sorted();
980}
981
982#[test]
983fn test_event_queue_push_sorted() {
984 let mut queue = EventQueue::new();
985 queue.push_unsorted(point(5.0, 0.0));
986 queue.push_unsorted(point(4.0, 0.0));
987 queue.push_unsorted(point(3.0, 0.0));
988 queue.push_unsorted(point(2.0, 0.0));
989 queue.push_unsorted(point(1.0, 0.0));
990 queue.push_unsorted(point(0.0, 0.0));
991
992 queue.sort();
993 queue.push_sorted(point(1.5, 0.0));
994 queue.assert_sorted();
995
996 queue.push_sorted(point(2.5, 0.0));
997 queue.assert_sorted();
998
999 queue.push_sorted(point(2.5, 0.0));
1000 queue.assert_sorted();
1001
1002 queue.push_sorted(point(6.5, 0.0));
1003 queue.assert_sorted();
1004}
1005
1006#[test]
1007fn test_logo() {
1008 use crate::path::Path;
1009
1010 let mut path = Path::builder().with_svg();
1011
1012 crate::extra::rust_logo::build_logo_path(&mut path);
1013 let path = path.build();
1014
1015 crate::extra::debugging::find_reduced_test_case(path.as_slice(), &|path: Path| {
1016 let _ = EventQueue::from_path(0.05, path.iter());
1017 true
1018 });
1019}