use crate::geom::math::*;
use crate::geometry_builder::*;
use crate::path::builder::{Build, FlatPathBuilder, PathBuilder};
use crate::path::{Path, PathSlice};
use crate::extra::rust_logo::build_logo_path;
use crate::{FillTessellator, TessellationError, FillOptions, FillVertex, OnError};
use std::env;
type Vertex = FillVertex;
fn tessellate_path(path: PathSlice, log: bool) -> Result<usize, TessellationError> {
let mut buffers: VertexBuffers<Vertex, u16> = VertexBuffers::new();
{
let mut vertex_builder = simple_builder(&mut buffers);
let mut tess = FillTessellator::new();
if log {
tess.enable_logging();
}
tess.tessellate_path(
path.iter(),
&FillOptions::tolerance(0.05),
&mut vertex_builder
)?;
}
return Ok(buffers.indices.len() / 3);
}
fn test_path(path: PathSlice) {
test_path_internal(path, None);
}
fn test_path_and_count_triangles(path: PathSlice, expected_triangle_count: usize) {
test_path_internal(path, Some(expected_triangle_count));
}
fn test_path_internal(path: PathSlice, expected_triangle_count: Option<usize>) {
let add_logging = env::var("LYON_ENABLE_LOGGING").is_ok();
let find_test_case = env::var("LYON_REDUCED_TESTCASE").is_ok();
let res = if find_test_case {
::std::panic::catch_unwind(|| tessellate_path(path, false))
} else {
Ok(tessellate_path(path, false))
};
if let Ok(Ok(num_triangles)) = res {
if let Some(expected_triangles) = expected_triangle_count {
if num_triangles != expected_triangles {
tessellate_path(path, add_logging).unwrap();
panic!("expected {} triangles, got {}", expected_triangles, num_triangles);
}
}
return;
}
if find_test_case {
crate::extra::debugging::find_reduced_test_case(
path,
&|path: Path| { return tessellate_path(path.as_slice(), false).is_err(); },
);
if add_logging {
tessellate_path(path, true).unwrap();
}
}
panic!();
}
fn test_path_with_rotations(path: Path, step: f32, expected_triangle_count: Option<usize>) {
use std::f32::consts::PI;
let mut angle = 0.0;
while angle < PI * 2.0 {
println!("\n\n ==================== angle = {}", angle);
let mut tranformed_path = path.clone();
let cos = angle.cos();
let sin = angle.sin();
for v in tranformed_path.mut_points() {
let (x, y) = (v.x, v.y);
v.x = x * cos + y * sin;
v.y = y * cos - x * sin;
}
test_path_internal(tranformed_path.as_slice(), expected_triangle_count);
angle += step;
}
}
#[test]
fn test_too_many_vertices() {
struct Builder { max_vertices: u32 }
impl<T> GeometryBuilder<T> for Builder
{
fn add_vertex(&mut self, _: T) -> Result<VertexId, GeometryBuilderError> {
if self.max_vertices == 0 {
return Err(GeometryBuilderError::TooManyVertices);
}
self.max_vertices -= 1;
Ok(VertexId(self.max_vertices))
}
fn begin_geometry(&mut self) {}
fn add_triangle(&mut self, _a: VertexId, _b: VertexId, _c: VertexId) {}
fn end_geometry(&mut self) -> Count { Count { vertices: 0, indices: 0 } }
fn abort_geometry(&mut self) {}
}
let mut path = Path::builder().with_svg();
build_logo_path(&mut path);
let path = path.build();
let mut tess = FillTessellator::new();
let mut options = FillOptions::tolerance(0.05);
options.on_error = OnError::Stop;
assert_eq!(
tess.tessellate_path(&path, &options, &mut Builder { max_vertices: 0 }),
Err(TessellationError::TooManyVertices),
);
assert_eq!(
tess.tessellate_path(&path, &options, &mut Builder { max_vertices: 10 }),
Err(TessellationError::TooManyVertices),
);
assert_eq!(
tess.tessellate_path(&path, &options, &mut Builder { max_vertices: 100 }),
Err(TessellationError::TooManyVertices),
);
}
#[test]
fn test_simple_triangle() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(1.0, 1.0));
path.line_to(point(0.0, 1.0));
path.close();
test_path_with_rotations(path.build(), 0.01, Some(1));
}
#[test]
fn test_simple_monotone() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(-1.0, 1.0));
path.line_to(point(-3.0, 2.0));
path.line_to(point(-1.0, 3.0));
path.line_to(point(-4.0, 5.0));
path.line_to(point(0.0, 6.0));
path.close();
let path = path.build();
test_path_and_count_triangles(path.as_slice(), 4);
}
#[test]
fn test_simple_split() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(2.0, 1.0));
path.line_to(point(2.0, 3.0));
path.line_to(point(1.0, 2.0));
path.line_to(point(0.0, 3.0));
path.close();
test_path_with_rotations(path.build(), 0.001, Some(3));
}
#[test]
fn test_simple_merge_split() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(1.0, 1.0));
path.line_to(point(2.0, 0.0));
path.line_to(point(2.0, 3.0));
path.line_to(point(1.0, 2.0));
path.line_to(point(0.0, 3.0));
path.close();
test_path_with_rotations(path.build(), 0.001, Some(4));
}
#[test]
fn test_simple_aligned() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(1.0, 0.0));
path.line_to(point(2.0, 0.0));
path.line_to(point(2.0, 1.0));
path.line_to(point(2.0, 2.0));
path.line_to(point(1.0, 2.0));
path.line_to(point(0.0, 2.0));
path.line_to(point(0.0, 1.0));
path.close();
test_path_with_rotations(path.build(), 0.001, Some(6));
}
#[test]
fn test_simple_1() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(1.0, 1.0));
path.line_to(point(2.0, 0.0));
path.line_to(point(1.0, 3.0));
path.line_to(point(0.5, 4.0));
path.line_to(point(0.0, 3.0));
path.close();
test_path_with_rotations(path.build(), 0.001, Some(4));
}
#[test]
fn test_simple_2() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(1.0, 0.0));
path.line_to(point(2.0, 0.0));
path.line_to(point(3.0, 0.0));
path.line_to(point(3.0, 1.0));
path.line_to(point(3.0, 2.0));
path.line_to(point(3.0, 3.0));
path.line_to(point(2.0, 3.0));
path.line_to(point(1.0, 3.0));
path.line_to(point(0.0, 3.0));
path.line_to(point(0.0, 2.0));
path.line_to(point(0.0, 1.0));
path.close();
test_path_with_rotations(path.build(), 0.001, Some(10));
}
#[test]
fn test_hole_1() {
let mut path = Path::builder();
path.move_to(point(-11.0, 5.0));
path.line_to(point(0.0, -5.0));
path.line_to(point(10.0, 5.0));
path.close();
path.move_to(point(-5.0, 2.0));
path.line_to(point(0.0, -2.0));
path.line_to(point(4.0, 2.0));
path.close();
test_path_with_rotations(path.build(), 0.001, Some(6));
}
#[test]
fn test_degenerate_same_position() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(0.0, 0.0));
path.line_to(point(0.0, 0.0));
path.line_to(point(0.0, 0.0));
path.line_to(point(0.0, 0.0));
path.line_to(point(0.0, 0.0));
path.close();
test_path_with_rotations(path.build(), 0.001, None);
}
#[test]
fn test_intersecting_bow_tie() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(2.0, 2.0));
path.line_to(point(2.0, 0.0));
path.line_to(point(0.0, 2.0));
path.close();
test_path(path.build().as_slice());
}
#[test]
fn test_auto_intersection_type1() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(2.0, 1.0));
path.line_to(point(0.0, 2.0));
path.line_to(point(2.0, 3.0));
path.close();
let path = path.build();
test_path_and_count_triangles(path.as_slice(), 2);
}
#[test]
fn test_auto_intersection_type2() {
let mut path = Path::builder();
path.move_to(point(0.0, 0.0));
path.line_to(point(2.0, 3.0));
path.line_to(point(2.0, 1.0));
path.line_to(point(0.0, 2.0));
path.close();
let path = path.build();
test_path_and_count_triangles(path.as_slice(), 2);
}
#[test]
fn test_auto_intersection_multi() {
let mut path = Path::builder();
path.move_to(point(20.0, 20.0));
path.line_to(point(60.0, 20.0));
path.line_to(point(60.0, 60.0));
path.line_to(point(20.0, 60.0));
path.close();
path.move_to(point(40.0, 10.0));
path.line_to(point(70.0, 40.0));
path.line_to(point(40.0, 70.0));
path.line_to(point(10.0, 40.0));
path.close();
let path = path.build();
test_path_with_rotations(path, 0.011, Some(8));
}
#[test]
fn test_rust_logo_no_intersection() {
let mut path = Path::builder().flattened(0.011).with_svg();
build_logo_path(&mut path);
test_path_with_rotations(path.build(), 0.011, None);
}
#[test]
fn test_rust_logo_with_intersection() {
let mut path = Path::builder().flattened(0.011).with_svg();
build_logo_path(&mut path);
path.move_to(point(10.0, 30.0));
path.line_to(point(130.0, 30.0));
path.line_to(point(130.0, 60.0));
path.line_to(point(10.0, 60.0));
path.close();
let path = path.build();
test_path_with_rotations(path, 0.011, None);
}
#[cfg(test)]
fn scale_path(path: &mut Path, scale: f32) {
for v in path.mut_points() {
*v = *v * scale;
}
}
#[test]
fn test_rust_logo_scale_up() {
let mut builder = Path::builder().with_svg();
build_logo_path(&mut builder);
let mut path = builder.build();
scale_path(&mut path, 260.0);
test_path(path.as_slice());
}
#[test]
fn test_rust_logo_scale_down() {
let mut builder = Path::builder().flattened(0.011).with_svg();
build_logo_path(&mut builder);
let mut path = builder.build();
scale_path(&mut path, 0.005);
test_path(path.as_slice());
}
#[test]
fn test_rust_logo_scale_down2() {
let mut builder = Path::builder().flattened(0.011).with_svg();
build_logo_path(&mut builder);
let mut path = builder.build();
scale_path(&mut path, 0.0000001);
test_path(path.as_slice());
}
#[test]
fn test_simple_double_merge() {
let mut path = Path::builder();
path.move_to(point(0.0, 2.0));
path.line_to(point(1.0, 3.0));
path.line_to(point(2.0, 0.0));
path.line_to(point(3.0, 2.0));
path.line_to(point(4.0, 1.0));
path.line_to(point(2.0, 6.0));
path.close();
}
#[test]
fn test_double_merge_with_intersection() {
let mut path = Path::builder();
path.move_to(point(80.041534, 19.24472));
path.line_to(point(76.56131, 23.062233));
path.line_to(point(67.26949, 23.039438));
path.line_to(point(65.989944, 23.178522));
path.line_to(point(59.90927, 19.969215));
path.line_to(point(56.916714, 25.207449));
path.line_to(point(50.333813, 23.25274));
path.line_to(point(48.42367, 28.978098));
path.close();
path.move_to(point(130.32213, 28.568213));
path.line_to(point(130.65213, 58.5664));
path.line_to(point(10.659382, 59.88637));
path.close();
test_path(path.build().as_slice());
}
#[test]
fn test_chained_merge_end() {
let mut path = Path::builder();
path.move_to(point(1.0, 0.0));
path.line_to(point(2.0, 1.0)); path.line_to(point(3.0, 0.0));
path.line_to(point(4.0, 2.0)); path.line_to(point(5.0, 0.0));
path.line_to(point(6.0, 3.0)); path.line_to(point(7.0, 0.0));
path.line_to(point(5.0, 8.0)); path.close();
test_path_and_count_triangles(path.build().as_slice(), 6);
}
#[test]
fn test_chained_merge_left() {
let mut path = Path::builder();
path.move_to(point(1.0, 0.0));
path.line_to(point(2.0, 1.0)); path.line_to(point(3.0, 0.0));
path.line_to(point(4.0, 2.0)); path.line_to(point(5.0, 0.0));
path.line_to(point(6.0, 3.0)); path.line_to(point(7.0, 0.0));
path.line_to(point(7.0, 5.0));
path.line_to(point(0.0, 4.0)); path.close();
test_path_and_count_triangles(path.build().as_slice(), 7);
}
#[test]
fn test_chained_merge_merge() {
let mut path = Path::builder();
path.move_to(point(1.0, 0.0));
path.line_to(point(2.0, 1.0)); path.line_to(point(3.0, 0.0));
path.line_to(point(4.0, 2.0)); path.line_to(point(5.0, 0.0));
path.line_to(point(6.0, 3.0)); path.line_to(point(7.0, 0.0));
path.line_to(point(7.0, 5.0));
path.line_to(point(-1.0, 5.0));
path.line_to(point(-1.0, 0.0));
path.line_to(point(0.0, 4.0)); path.close();
test_path_and_count_triangles(path.build().as_slice(), 9);
}
#[test]
fn test_chained_merge_split() {
let mut path = Path::builder();
path.move_to(point(1.0, 0.0));
path.line_to(point(2.0, 1.0)); path.line_to(point(3.0, 0.0));
path.line_to(point(4.0, 2.0)); path.line_to(point(5.0, 0.0));
path.line_to(point(6.0, 3.0)); path.line_to(point(7.0, 0.0));
path.line_to(point(7.0, 5.0));
path.line_to(point(4.0, 4.0)); path.line_to(point(1.0, 5.0));
path.close();
test_path_and_count_triangles(path.build().as_slice(), 8);
}
#[test]
fn test_intersection_horizontal_precision() {
let mut builder = Path::builder();
builder.move_to(point(-34.619564, 111.88655));
builder.line_to(point(-35.656174, 111.891));
builder.line_to(point(-39.304527, 121.766914));
builder.close();
builder.move_to(point(1.4426613, 133.40884));
builder.line_to(point(-27.714422, 140.47032));
builder.line_to(point(-55.960342, 23.841988));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn test_overlapping_with_intersection() {
let mut builder = Path::builder();
builder.move_to(point(2.0, -1.0));
builder.line_to(point(2.0, -3.0));
builder.line_to(point(3.0, -2.0));
builder.line_to(point(1.0, -2.0));
builder.line_to(point(2.0, -3.0));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn test_split_with_intersections() {
let mut builder = Path::builder();
builder.move_to(point(-21.004179, -71.57515));
builder.line_to(point(-21.927473, -70.94977));
builder.line_to(point(-23.024633, -70.68942));
builder.close();
builder.move_to(point(16.036617, -27.254852));
builder.line_to(point(-62.83691, -117.69249));
builder.line_to(point(38.646027, -46.973236));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_colinear_1() {
let mut builder = Path::builder();
builder.move_to(point(20.0, 150.0));
builder.line_to(point(80.0, 150.0));
builder.close();
let path = builder.build();
test_path_with_rotations(path, 0.01, None);
}
#[test]
fn test_colinear_2() {
let mut builder = Path::builder();
builder.move_to(point(20.0, 150.0));
builder.line_to(point(80.0, 150.0));
builder.line_to(point(20.0, 150.0));
builder.close();
let path = builder.build();
test_path_with_rotations(path, 0.01, None);
}
#[test]
fn test_colinear_3() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 1.0));
builder.line_to(point(0.0, 3.0));
builder.line_to(point(0.0, 5.0));
builder.line_to(point(0.0, 4.0));
builder.line_to(point(0.0, 2.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_colinear_4() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 2.0));
builder.line_to(point(0.0, 1.0));
builder.line_to(point(0.0, 3.0));
builder.line_to(point(0.0, 0.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_colinear_touching_squares() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(1.0, 0.0));
builder.line_to(point(1.0, 1.0));
builder.line_to(point(0.0, 1.0));
builder.move_to(point(1.0, 0.0));
builder.line_to(point(2.0, 0.0));
builder.line_to(point(2.0, 1.0));
builder.line_to(point(1.0, 1.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn angle_precision() {
let mut builder = Path::builder();
builder.move_to(point(0.007982401, 0.0121872));
builder.line_to(point(0.008415101, 0.0116545));
builder.line_to(point(0.008623006, 0.011589845));
builder.line_to(point(0.008464893, 0.011639819));
builder.line_to(point(0.0122631, 0.0069716));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn n_segments_intersecting() {
use std::f32::consts::PI;
for i in 1..10 {
let mut builder = Path::builder();
let center = point(-2.0, -5.0);
let n = i * 4 - 1;
let delta = PI / n as f32;
let mut radius = 1000.0;
builder.move_to(center + vector(radius, 0.0));
builder.line_to(center - vector(-radius, 0.0));
for i in 0..n {
let (s, c) = (i as f32 * delta).sin_cos();
builder.line_to(center + vector(c, s) * radius);
builder.line_to(center - vector(c, s) * radius);
radius = -radius;
}
builder.close();
test_path_with_rotations(builder.build(), 0.03, None);
}
}
#[test]
fn back_along_previous_edge() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(1.0, 1.0));
builder.line_to(point(0.8, 0.8));
builder.line_to(point(1.5, 1.5));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn test_colinear_touching_squares2() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(10.0, 0.0));
builder.line_to(point(10.0, 10.0));
builder.line_to(point(0.0, 10.0));
builder.move_to(point(10.0, 1.0));
builder.line_to(point(20.0, 1.0));
builder.line_to(point(20.0, 11.0));
builder.line_to(point(10.0, 11.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_colinear_touching_squares3() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 1.0));
builder.line_to(point(10.0, 1.0));
builder.line_to(point(10.0, 11.0));
builder.line_to(point(0.0, 11.0));
builder.move_to(point(10.0, 0.0));
builder.line_to(point(20.0, 0.0));
builder.line_to(point(20.0, 10.0));
builder.line_to(point(10.0, 10.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_unknown_issue_1() {
let mut builder = Path::builder();
builder.move_to(point(-3.3709216, 9.467676));
builder.line_to(point(-13.078612, 7.0675235));
builder.line_to(point(-10.67846, -2.6401677));
builder.close();
builder.move_to(point(-4.800305, 19.415382));
builder.line_to(point(-14.507996, 17.01523));
builder.line_to(point(-12.107843, 7.307539));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn test_colinear_touching_squares_rotated() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 1.0));
builder.line_to(point(10.0, 1.0));
builder.line_to(point(10.0, 11.0));
builder.line_to(point(0.0, 11.0));
builder.move_to(point(10.0, 0.0));
builder.line_to(point(20.0, 0.0));
builder.line_to(point(20.0, 10.0));
builder.line_to(point(10.0, 10.0));
builder.close();
let path = builder.build();
test_path_with_rotations(path, 0.01, None)
}
#[test]
fn test_point_on_edge_right() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(0.0, 100.0));
builder.line_to(point(50.0, 100.0));
builder.line_to(point(0.0, 50.0));
builder.line_to(point(-50.0, 100.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_point_on_edge_left() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(0.0, 100.0));
builder.line_to(point(-50.0, 100.0));
builder.line_to(point(0.0, 50.0));
builder.line_to(point(50.0, 100.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_point_on_edge2() {
let mut builder = Path::builder();
builder.move_to(point(1.0, 1.0));
builder.line_to(point(2.0, 1.0));
builder.line_to(point(3.0, 1.0));
builder.line_to(point(3.0, 2.0));
builder.line_to(point(1.0, 2.0));
builder.close();
builder.move_to(point(2.0, 0.0));
builder.line_to(point(2.0, 3.0));
builder.line_to(point(4.0, 3.0));
builder.line_to(point(4.0, 0.0));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn test_coincident_simple() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(1.0, 1.0)); builder.line_to(point(0.0, 2.0));
builder.line_to(point(2.0, 2.0));
builder.line_to(point(1.0, 1.0)); builder.line_to(point(2.0, 0.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_coincident_simple_2() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(1.0, 1.0)); builder.line_to(point(2.0, 0.0));
builder.line_to(point(2.0, 2.0));
builder.line_to(point(1.0, 1.0)); builder.line_to(point(0.0, 2.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_coincident_simple_rotated() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(1.0, 1.0)); builder.line_to(point(0.0, 2.0));
builder.line_to(point(2.0, 2.0));
builder.line_to(point(1.0, 1.0)); builder.line_to(point(2.0, 0.0));
builder.close();
let path = builder.build();
test_path_with_rotations(path, 0.01, None);
}
#[test]
fn test_identical_squares() {
let mut builder = Path::builder();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(1.0, 0.0));
builder.line_to(point(1.0, 1.0));
builder.line_to(point(0.0, 1.0));
builder.close();
builder.move_to(point(0.0, 0.0));
builder.line_to(point(1.0, 0.0));
builder.line_to(point(1.0, 1.0));
builder.line_to(point(0.0, 1.0));
builder.close();
let path = builder.build();
test_path(path.as_slice());
}
#[test]
fn test_close_at_first_position() {
let mut builder = Path::builder();
builder.move_to(point(107.400665, 91.79798));
builder.line_to(point(108.93136, 91.51076));
builder.line_to(point(107.84248, 91.79686));
builder.line_to(point(107.400665, 91.79798));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn test_fixed_to_f32_precision() {
let mut builder = Path::builder();
builder.move_to(point(68.97998, 796.05));
builder.line_to(point(61.27998, 805.35));
builder.line_to(point(55.37999, 799.14996));
builder.line_to(point(68.98, 796.05));
builder.close();
test_path(builder.build().as_slice());
}
#[test]
fn test_no_close() {
let mut builder = Path::builder();
builder.move_to(point(1.0, 1.0));
builder.line_to(point(5.0, 1.0));
builder.line_to(point(1.0, 5.0));
test_path(builder.build().as_slice());
}
#[test]
fn test_empty_path() {
test_path_and_count_triangles(Path::new().as_slice(), 0);
}
#[test]
fn test_exp_no_intersection_01() {
let mut builder = Path::builder();
builder.move_to(point(80.041534, 19.24472));
builder.line_to(point(76.56131, 23.062233));
builder.line_to(point(67.26949, 23.039438));
builder.line_to(point(48.42367, 28.978098));
builder.close();
test_path(builder.build().as_slice());
}