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: 0,
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 clear(&mut self) {
277 self.events.clear();
278 self.first = INVALID_EVENT_ID;
279 self.sorted = false;
280 }
281
282 pub(crate) fn first_id(&self) -> TessEventId {
284 self.first
285 }
286
287 pub(crate) fn next_id(&self, id: TessEventId) -> TessEventId {
289 self.events[id as usize].next_event
290 }
291
292 pub(crate) fn next_sibling_id(&self, id: TessEventId) -> TessEventId {
294 self.events[id as usize].next_sibling
295 }
296
297 pub(crate) fn valid_id(&self, id: TessEventId) -> bool {
299 id != INVALID_EVENT_ID
300 }
301
302 pub(crate) fn position(&self, id: TessEventId) -> Point {
304 self.events[id as usize].position
305 }
306
307 fn sort(&mut self) {
308 self.sorted = true;
309
310 if self.events.is_empty() {
311 return;
312 }
313
314 let range = 0..self.events.len();
315 self.first = self.merge_sort(range);
316 }
317
318 fn merge_sort(&mut self, range: Range<usize>) -> TessEventId {
324 let split = (range.start + range.end) / 2;
325
326 if split == range.start {
327 return range.start as TessEventId;
328 }
329
330 let a_head = self.merge_sort(range.start..split);
331 let b_head = self.merge_sort(split..range.end);
332
333 self.merge(a_head, b_head)
334 }
335
336 fn merge(&mut self, mut a: TessEventId, mut b: TessEventId) -> TessEventId {
337 if a == INVALID_EVENT_ID {
338 return b;
339 }
340 if b == INVALID_EVENT_ID {
341 return a;
342 }
343
344 debug_assert!(a != b);
345 let mut first = true;
346 let mut sorted_head = INVALID_EVENT_ID;
347 let mut prev = INVALID_EVENT_ID;
348
349 loop {
350 if a == INVALID_EVENT_ID {
351 if !first {
352 self.events[prev as usize].next_event = b;
353 }
354 break;
355 }
356
357 if b == INVALID_EVENT_ID {
358 if !first {
359 self.events[prev as usize].next_event = a;
360 }
361 break;
362 }
363
364 let node;
365 match compare_positions(
366 self.events[a as usize].position,
367 self.events[b as usize].position,
368 ) {
369 Ordering::Less => {
370 node = a;
371 a = self.events[a as usize].next_event;
372 }
373 Ordering::Greater => {
374 node = b;
375 b = self.events[b as usize].next_event;
376 }
377 Ordering::Equal => {
378 let a_sib = self.find_last_sibling(a) as usize;
380 self.events[a_sib].next_sibling = b;
381
382 b = self.events[b as usize].next_event;
383
384 continue;
385 }
386 }
387
388 if first {
389 first = false;
390 sorted_head = node;
391 } else {
392 self.events[prev as usize].next_event = node;
393 }
394
395 prev = node;
396 }
397
398 if sorted_head == INVALID_EVENT_ID {
399 sorted_head = a;
400 }
401
402 sorted_head
403 }
404
405 fn find_last_sibling(&self, id: TessEventId) -> TessEventId {
406 let mut current_sibling = id;
407 let mut next_sibling = self.next_sibling_id(id);
408 while self.valid_id(next_sibling) {
409 current_sibling = next_sibling;
410 next_sibling = self.next_sibling_id(current_sibling);
411 }
412
413 current_sibling
414 }
415
416 #[cfg(all(debug_assertions, feature = "std"))]
417 fn log(&self) {
418 let mut iter_count = self.events.len() * self.events.len();
419
420 std::println!("--");
421 let mut current = self.first;
422 while (current as usize) < self.events.len() {
423 assert!(iter_count > 0);
424 iter_count -= 1;
425
426 std::print!("[");
427 let mut current_sibling = current;
428 while (current_sibling as usize) < self.events.len() {
429 std::print!("{:?},", self.events[current_sibling as usize].position);
430 current_sibling = self.events[current_sibling as usize].next_sibling;
431 }
432 std::print!("] ");
433 current = self.events[current as usize].next_event;
434 }
435 std::println!("\n--");
436 }
437
438 fn assert_sorted(&self) {
439 let mut current = self.first;
440 let mut pos = point(f32::MIN, f32::MIN);
441 let mut n = 0;
442 while self.valid_id(current) {
443 assert!(is_after(self.events[current as usize].position, pos));
444 pos = self.events[current as usize].position;
445 let mut current_sibling = current;
446 while self.valid_id(current_sibling) {
447 n += 1;
448 assert_eq!(self.events[current_sibling as usize].position, pos);
449 current_sibling = self.next_sibling_id(current_sibling);
450 }
451 current = self.next_id(current);
452 }
453 assert_eq!(n, self.events.len());
454 }
455}
456
457pub struct EventQueueBuilder {
458 current: Point,
459 prev: Point,
460 second: Point,
461 nth: u32,
462 queue: EventQueue,
463 tolerance: f32,
464 prev_endpoint_id: EndpointId,
465 validator: DebugValidator,
466}
467
468impl EventQueueBuilder {
469 pub fn new(tolerance: f32) -> Self {
470 EventQueue::new().into_builder(tolerance)
471 }
472
473 pub fn with_capacity(cap: usize, tolerance: f32) -> Self {
474 EventQueue::with_capacity(cap).into_builder(tolerance)
475 }
476
477 pub fn set_tolerance(&mut self, tolerance: f32) {
478 self.tolerance = tolerance;
479 }
480
481 pub fn build(mut self) -> EventQueue {
482 self.validator.build();
483
484 self.queue.sort();
485
486 self.queue
487 }
488
489 pub fn set_path(
490 &mut self,
491 tolerance: f32,
492 sweep_orientation: Orientation,
493 path: impl IntoIterator<Item = PathEvent>,
494 ) {
495 self.reset();
496
497 self.tolerance = tolerance;
498 let endpoint_id = EndpointId(u32::MAX);
499 match sweep_orientation {
500 Orientation::Vertical => {
501 for evt in path {
502 match evt {
503 PathEvent::Begin { at } => {
504 self.begin(at, endpoint_id);
505 }
506 PathEvent::Line { to, .. } => {
507 self.line_segment(to, endpoint_id, 0.0, 1.0);
508 }
509 PathEvent::Quadratic { ctrl, to, .. } => {
510 self.quadratic_bezier_segment(ctrl, to, endpoint_id);
511 }
512 PathEvent::Cubic {
513 ctrl1, ctrl2, to, ..
514 } => {
515 self.cubic_bezier_segment(ctrl1, ctrl2, to, endpoint_id);
516 }
517 PathEvent::End { first, .. } => {
518 self.end(first, endpoint_id);
519 }
520 }
521 }
522 }
523
524 Orientation::Horizontal => {
525 for evt in path {
526 match evt {
527 PathEvent::Begin { at } => {
528 self.begin(reorient(at), endpoint_id);
529 }
530 PathEvent::Line { to, .. } => {
531 self.line_segment(reorient(to), endpoint_id, 0.0, 1.0);
532 }
533 PathEvent::Quadratic { ctrl, to, .. } => {
534 self.quadratic_bezier_segment(
535 reorient(ctrl),
536 reorient(to),
537 endpoint_id,
538 );
539 }
540 PathEvent::Cubic {
541 ctrl1, ctrl2, to, ..
542 } => {
543 self.cubic_bezier_segment(
544 reorient(ctrl1),
545 reorient(ctrl2),
546 reorient(to),
547 endpoint_id,
548 );
549 }
550 PathEvent::End { first, .. } => {
551 self.end(reorient(first), endpoint_id);
552 }
553 }
554 }
555 }
556 }
557 }
558
559 pub fn set_path_with_ids(
560 &mut self,
561 tolerance: f32,
562 sweep_orientation: Orientation,
563 path_events: impl IntoIterator<Item = IdEvent>,
564 points: &impl PositionStore,
565 ) {
566 self.reset();
567
568 self.tolerance = tolerance;
569 match sweep_orientation {
570 Orientation::Vertical => {
571 for evt in path_events {
572 match evt {
573 IdEvent::Begin { at } => {
574 self.begin(points.get_endpoint(at), at);
575 }
576 IdEvent::Line { to, .. } => {
577 self.line_segment(points.get_endpoint(to), to, 0.0, 1.0);
578 }
579 IdEvent::Quadratic { ctrl, to, .. } => {
580 self.quadratic_bezier_segment(
581 points.get_control_point(ctrl),
582 points.get_endpoint(to),
583 to,
584 );
585 }
586 IdEvent::Cubic {
587 ctrl1, ctrl2, to, ..
588 } => {
589 self.cubic_bezier_segment(
590 points.get_control_point(ctrl1),
591 points.get_control_point(ctrl2),
592 points.get_endpoint(to),
593 to,
594 );
595 }
596 IdEvent::End { first, .. } => {
597 self.end(points.get_endpoint(first), first);
598 }
599 }
600 }
601 }
602
603 Orientation::Horizontal => {
604 for evt in path_events {
605 match evt {
606 IdEvent::Begin { at } => {
607 self.begin(reorient(points.get_endpoint(at)), at);
608 }
609 IdEvent::Line { to, .. } => {
610 self.line_segment(reorient(points.get_endpoint(to)), to, 0.0, 1.0);
611 }
612 IdEvent::Quadratic { ctrl, to, .. } => {
613 self.quadratic_bezier_segment(
614 reorient(points.get_control_point(ctrl)),
615 reorient(points.get_endpoint(to)),
616 to,
617 );
618 }
619 IdEvent::Cubic {
620 ctrl1, ctrl2, to, ..
621 } => {
622 self.cubic_bezier_segment(
623 reorient(points.get_control_point(ctrl1)),
624 reorient(points.get_control_point(ctrl2)),
625 reorient(points.get_endpoint(to)),
626 to,
627 );
628 }
629 IdEvent::End { first, .. } => {
630 self.end(reorient(points.get_endpoint(first)), first);
631 }
632 }
633 }
634 }
635 }
636 }
637
638 fn reset(&mut self) {
639 self.queue.reset();
640 self.nth = 0;
641 }
642
643 fn vertex_event(&mut self, at: Point, endpoint_id: EndpointId) {
644 self.queue.push_unsorted(at);
645 self.queue.edge_data.push(EdgeData {
646 to: point(f32::NAN, f32::NAN),
647 range: 0.0..0.0,
648 winding: 0,
649 is_edge: false,
650 from_id: endpoint_id,
651 to_id: endpoint_id,
652 });
653 }
654
655 fn vertex_event_on_curve(&mut self, at: Point, t: f32, from_id: EndpointId, to_id: EndpointId) {
656 self.queue.push_unsorted(at);
657 self.queue.edge_data.push(EdgeData {
658 to: point(f32::NAN, f32::NAN),
659 range: t..t,
660 winding: 0,
661 is_edge: false,
662 from_id,
663 to_id,
664 });
665 }
666
667 pub fn end(&mut self, first: Point, first_endpoint_id: EndpointId) {
668 if self.nth == 0 {
669 self.validator.end();
670 return;
671 }
672
673 self.line_segment(first, first_endpoint_id, 0.0, 1.0);
676
677 if is_after(first, self.prev) && is_after(first, self.second) {
681 self.vertex_event(first, first_endpoint_id);
682 }
683
684 self.validator.end();
685
686 self.prev_endpoint_id = first_endpoint_id;
687 self.nth = 0;
688 }
689
690 pub fn begin(&mut self, to: Point, to_id: EndpointId) {
691 self.validator.begin();
692
693 self.nth = 0;
694 self.current = to;
695 self.prev_endpoint_id = to_id;
696 }
697
698 #[allow(clippy::too_many_arguments)]
699 fn add_edge(
700 &mut self,
701 edge: &LineSegment<f32>,
702 mut winding: i16,
703 from_id: EndpointId,
704 to_id: EndpointId,
705 mut t0: f32,
706 mut t1: f32,
707 ) {
708 if edge.from == edge.to {
709 return;
710 }
711
712 let mut evt_pos = edge.from;
713 let mut evt_to = edge.to;
714 if is_after(evt_pos, edge.to) {
715 evt_to = evt_pos;
716 evt_pos = edge.to;
717 swap(&mut t0, &mut t1);
718 winding *= -1;
719 }
720
721 self.queue.push_unsorted(evt_pos);
722 self.queue.edge_data.push(EdgeData {
723 to: evt_to,
724 range: t0..t1,
725 winding,
726 is_edge: true,
727 from_id,
728 to_id,
729 });
730
731 self.nth += 1;
732 }
733
734 pub fn line_segment(&mut self, to: Point, to_id: EndpointId, t0: f32, t1: f32) {
735 self.validator.edge();
736
737 let from = self.current;
738 if from == to {
739 return;
740 }
741
742 if is_after(from, to) && self.nth > 0 && is_after(from, self.prev) {
743 self.vertex_event(from, self.prev_endpoint_id);
744 }
745
746 if self.nth == 0 {
747 self.second = to;
748 }
749
750 self.add_edge(
751 &LineSegment { from, to },
752 1,
753 self.prev_endpoint_id,
754 to_id,
755 t0,
756 t1,
757 );
758
759 self.prev = self.current;
760 self.prev_endpoint_id = to_id;
761 self.current = to;
762 }
763
764 pub fn quadratic_bezier_segment(&mut self, ctrl: Point, to: Point, to_id: EndpointId) {
765 self.validator.edge();
766 let original = QuadraticBezierSegment {
774 from: self.current,
775 ctrl,
776 to,
777 };
778
779 let needs_swap = is_after(original.from, original.to);
780
781 let mut segment = original;
782 let mut winding = 1;
783 if needs_swap {
784 swap(&mut segment.from, &mut segment.to);
785 winding = -1;
786 }
787
788 let mut prev = segment.from;
789 let mut first = None;
790 let is_first_edge = self.nth == 0;
791 segment.for_each_flattened_with_t(self.tolerance, &mut |line, t| {
792 if line.from == line.to {
793 return;
794 }
795
796 if first.is_none() {
797 first = Some(line.to)
798 } else if is_after(line.from, line.to) && is_after(line.from, prev) {
803 self.vertex_event_on_curve(line.from, t.start, self.prev_endpoint_id, to_id);
804 }
805
806 self.add_edge(line, winding, self.prev_endpoint_id, to_id, t.start, t.end);
807
808 prev = line.from;
809 });
810
811 if let Some(first) = first {
812 let (second, previous) = if needs_swap {
813 (prev, first)
814 } else {
815 (first, prev)
816 };
817
818 if is_first_edge {
819 self.second = second;
820 } else if is_after(original.from, self.prev) && is_after(original.from, second) {
821 self.vertex_event(original.from, self.prev_endpoint_id);
824 }
825
826 self.prev = previous;
827 self.current = original.to;
828 self.prev_endpoint_id = to_id;
829 }
830 }
831
832 pub fn cubic_bezier_segment(
833 &mut self,
834 ctrl1: Point,
835 ctrl2: Point,
836 to: Point,
837 to_id: EndpointId,
838 ) {
839 self.validator.edge();
840 let original = CubicBezierSegment {
848 from: self.current,
849 ctrl1,
850 ctrl2,
851 to,
852 };
853
854 let needs_swap = is_after(original.from, original.to);
855
856 let mut segment = original;
857 let mut winding = 1;
858 if needs_swap {
859 swap(&mut segment.from, &mut segment.to);
860 swap(&mut segment.ctrl1, &mut segment.ctrl2);
861 winding = -1;
862 }
863
864 let mut prev = segment.from;
865 let mut first = None;
866 let is_first_edge = self.nth == 0;
867 segment.for_each_flattened_with_t(self.tolerance, &mut |line, t| {
868 if line.from == line.to {
869 return;
870 }
871
872 if first.is_none() {
873 first = Some(line.to)
874 } else if is_after(line.from, line.to) && is_after(line.from, prev) {
879 self.vertex_event_on_curve(line.from, t.start, self.prev_endpoint_id, to_id);
880 }
881
882 self.add_edge(line, winding, self.prev_endpoint_id, to_id, t.start, t.end);
883
884 prev = line.from;
885 });
886
887 if let Some(first) = first {
888 let (second, previous) = if needs_swap {
889 (prev, first)
890 } else {
891 (first, prev)
892 };
893
894 if is_first_edge {
895 self.second = second;
896 } else if is_after(original.from, self.prev) && is_after(original.from, second) {
897 self.vertex_event(original.from, self.prev_endpoint_id);
900 }
901
902 self.prev = previous;
903 self.current = original.to;
904 self.prev_endpoint_id = to_id;
905 }
906 }
907
908 pub fn reserve(&mut self, n: usize) {
909 self.queue.reserve(n);
910 }
911}
912
913#[test]
914fn test_event_queue_sort_1() {
915 let mut queue = EventQueue::new();
916 queue.push_unsorted(point(0.0, 0.0));
917 queue.push_unsorted(point(4.0, 0.0));
918 queue.push_unsorted(point(2.0, 0.0));
919 queue.push_unsorted(point(3.0, 0.0));
920 queue.push_unsorted(point(4.0, 0.0));
921 queue.push_unsorted(point(0.0, 0.0));
922 queue.push_unsorted(point(6.0, 0.0));
923
924 queue.sort();
925 queue.assert_sorted();
926}
927
928#[test]
929fn test_event_queue_sort_2() {
930 let mut queue = EventQueue::new();
931 queue.push_unsorted(point(0.0, 0.0));
932 queue.push_unsorted(point(0.0, 0.0));
933 queue.push_unsorted(point(0.0, 0.0));
934 queue.push_unsorted(point(0.0, 0.0));
935
936 queue.sort();
937 queue.assert_sorted();
938}
939
940#[test]
941fn test_event_queue_sort_3() {
942 let mut queue = EventQueue::new();
943 queue.push_unsorted(point(0.0, 0.0));
944 queue.push_unsorted(point(1.0, 0.0));
945 queue.push_unsorted(point(2.0, 0.0));
946 queue.push_unsorted(point(3.0, 0.0));
947 queue.push_unsorted(point(4.0, 0.0));
948 queue.push_unsorted(point(5.0, 0.0));
949
950 queue.sort();
951 queue.assert_sorted();
952}
953
954#[test]
955fn test_event_queue_sort_4() {
956 let mut queue = EventQueue::new();
957 queue.push_unsorted(point(5.0, 0.0));
958 queue.push_unsorted(point(4.0, 0.0));
959 queue.push_unsorted(point(3.0, 0.0));
960 queue.push_unsorted(point(2.0, 0.0));
961 queue.push_unsorted(point(1.0, 0.0));
962 queue.push_unsorted(point(0.0, 0.0));
963
964 queue.sort();
965 queue.assert_sorted();
966}
967
968#[test]
969fn test_event_queue_sort_5() {
970 let mut queue = EventQueue::new();
971 queue.push_unsorted(point(5.0, 0.0));
972 queue.push_unsorted(point(5.0, 0.0));
973 queue.push_unsorted(point(4.0, 0.0));
974 queue.push_unsorted(point(4.0, 0.0));
975 queue.push_unsorted(point(3.0, 0.0));
976 queue.push_unsorted(point(3.0, 0.0));
977 queue.push_unsorted(point(2.0, 0.0));
978 queue.push_unsorted(point(2.0, 0.0));
979 queue.push_unsorted(point(1.0, 0.0));
980 queue.push_unsorted(point(1.0, 0.0));
981 queue.push_unsorted(point(0.0, 0.0));
982 queue.push_unsorted(point(0.0, 0.0));
983
984 queue.sort();
985 queue.assert_sorted();
986}
987
988#[test]
989fn test_event_queue_push_sorted() {
990 let mut queue = EventQueue::new();
991 queue.push_unsorted(point(5.0, 0.0));
992 queue.push_unsorted(point(4.0, 0.0));
993 queue.push_unsorted(point(3.0, 0.0));
994 queue.push_unsorted(point(2.0, 0.0));
995 queue.push_unsorted(point(1.0, 0.0));
996 queue.push_unsorted(point(0.0, 0.0));
997
998 queue.sort();
999 queue.push_sorted(point(1.5, 0.0));
1000 queue.assert_sorted();
1001
1002 queue.push_sorted(point(2.5, 0.0));
1003 queue.assert_sorted();
1004
1005 queue.push_sorted(point(2.5, 0.0));
1006 queue.assert_sorted();
1007
1008 queue.push_sorted(point(6.5, 0.0));
1009 queue.assert_sorted();
1010}
1011
1012#[test]
1013fn test_logo() {
1014 use crate::path::Path;
1015
1016 let mut path = Path::builder().with_svg();
1017
1018 crate::extra::rust_logo::build_logo_path(&mut path);
1019 let path = path.build();
1020
1021 crate::extra::debugging::find_reduced_test_case(path.as_slice(), &|path: Path| {
1022 let _ = EventQueue::from_path(0.05, path.iter());
1023 true
1024 });
1025}