#![doc(html_logo_url = "https://nical.github.io/lyon-doc/lyon-logo.svg")]
#![deny(bare_trait_objects)]
#![deny(unconditional_recursion)]
#![allow(clippy::many_single_char_names)]
#![allow(clippy::let_and_return)]
#![no_std]
#[cfg(any(test, feature = "std"))]
extern crate std;
pub use arrayvec;
pub use euclid;
#[cfg(feature = "serialization")]
#[macro_use]
pub extern crate serde;
#[macro_use]
mod segment;
pub mod arc;
pub mod cubic_bezier;
mod cubic_bezier_intersections;
mod line;
pub mod quadratic_bezier;
mod triangle;
pub mod utils;
#[doc(inline)]
pub use crate::arc::{Arc, ArcFlags, SvgArc};
#[doc(inline)]
pub use crate::cubic_bezier::CubicBezierSegment;
#[doc(inline)]
pub use crate::line::{Line, LineEquation, LineSegment};
#[doc(inline)]
pub use crate::quadratic_bezier::QuadraticBezierSegment;
#[doc(inline)]
pub use crate::segment::Segment;
#[doc(inline)]
pub use crate::triangle::Triangle;
pub use crate::scalar::Scalar;
mod scalar {
pub(crate) use euclid::Trig;
pub(crate) use num_traits::cast::cast;
pub(crate) use num_traits::{Float, FloatConst, NumCast};
use core::fmt::{Debug, Display};
use core::ops::{AddAssign, DivAssign, MulAssign, SubAssign};
pub trait Scalar:
Float
+ NumCast
+ FloatConst
+ Sized
+ Display
+ Debug
+ Trig
+ AddAssign
+ SubAssign
+ MulAssign
+ DivAssign
{
const HALF: Self;
const ZERO: Self;
const ONE: Self;
const TWO: Self;
const THREE: Self;
const FOUR: Self;
const FIVE: Self;
const SIX: Self;
const SEVEN: Self;
const EIGHT: Self;
const NINE: Self;
const TEN: Self;
const MIN: Self;
const MAX: Self;
const EPSILON: Self;
const DIV_EPSILON: Self = Self::EPSILON;
fn epsilon_for(_reference: Self) -> Self {
Self::EPSILON
}
fn value(v: f32) -> Self;
}
impl Scalar for f32 {
const HALF: Self = 0.5;
const ZERO: Self = 0.0;
const ONE: Self = 1.0;
const TWO: Self = 2.0;
const THREE: Self = 3.0;
const FOUR: Self = 4.0;
const FIVE: Self = 5.0;
const SIX: Self = 6.0;
const SEVEN: Self = 7.0;
const EIGHT: Self = 8.0;
const NINE: Self = 9.0;
const TEN: Self = 10.0;
const MIN: Self = core::f32::MIN;
const MAX: Self = core::f32::MAX;
const EPSILON: Self = 1e-4;
#[inline]
fn value(v: f32) -> Self {
v
}
fn epsilon_for(reference: Self) -> Self {
let magnitude = reference.abs() as i32;
match magnitude {
0..=7 => 1e-5,
8..=1023 => 1e-3,
1024..=4095 => 1e-2,
5096..=65535 => 1e-1,
65536..=8_388_607 => 0.5,
_ => 1.0,
}
}
}
impl Scalar for f64 {
const HALF: Self = 0.5;
const ZERO: Self = 0.0;
const ONE: Self = 1.0;
const TWO: Self = 2.0;
const THREE: Self = 3.0;
const FOUR: Self = 4.0;
const FIVE: Self = 5.0;
const SIX: Self = 6.0;
const SEVEN: Self = 7.0;
const EIGHT: Self = 8.0;
const NINE: Self = 9.0;
const TEN: Self = 10.0;
const MIN: Self = core::f64::MIN;
const MAX: Self = core::f64::MAX;
const EPSILON: Self = 1e-8;
#[inline]
fn value(v: f32) -> Self {
v as f64
}
fn epsilon_for(reference: Self) -> Self {
let magnitude = reference.abs() as i64;
match magnitude {
0..=65_535 => 1e-8,
65_536..=8_388_607 => 1e-5,
8_388_608..=4_294_967_295 => 1e-3,
_ => 1e-1,
}
}
}
}
pub use euclid::default::Point2D as Point;
pub use euclid::default::Vector2D as Vector;
pub use euclid::default::Size2D as Size;
pub use euclid::default::Box2D;
pub type Transform<S> = euclid::default::Transform2D<S>;
pub type Rotation<S> = euclid::default::Rotation2D<S>;
pub type Translation<S> = euclid::Translation2D<S, euclid::UnknownUnit, euclid::UnknownUnit>;
pub use euclid::default::Scale;
pub use euclid::Angle;
#[inline]
pub fn vector<S>(x: S, y: S) -> Vector<S> {
Vector::new(x, y)
}
#[inline]
pub fn point<S>(x: S, y: S) -> Point<S> {
Point::new(x, y)
}
#[inline]
pub fn size<S>(w: S, h: S) -> Size<S> {
Size::new(w, h)
}
pub mod traits {
pub use crate::segment::Segment;
use crate::{Point, Rotation, Scalar, Scale, Transform, Translation, Vector};
pub trait Transformation<S> {
fn transform_point(&self, p: Point<S>) -> Point<S>;
fn transform_vector(&self, v: Vector<S>) -> Vector<S>;
}
impl<S: Scalar> Transformation<S> for Transform<S> {
fn transform_point(&self, p: Point<S>) -> Point<S> {
self.transform_point(p)
}
fn transform_vector(&self, v: Vector<S>) -> Vector<S> {
self.transform_vector(v)
}
}
impl<S: Scalar> Transformation<S> for Rotation<S> {
fn transform_point(&self, p: Point<S>) -> Point<S> {
self.transform_point(p)
}
fn transform_vector(&self, v: Vector<S>) -> Vector<S> {
self.transform_vector(v)
}
}
impl<S: Scalar> Transformation<S> for Translation<S> {
fn transform_point(&self, p: Point<S>) -> Point<S> {
self.transform_point(p)
}
fn transform_vector(&self, v: Vector<S>) -> Vector<S> {
v
}
}
impl<S: Scalar> Transformation<S> for Scale<S> {
fn transform_point(&self, p: Point<S>) -> Point<S> {
(*self).transform_point(p)
}
fn transform_vector(&self, v: Vector<S>) -> Vector<S> {
(*self).transform_vector(v)
}
}
impl<'l, S: Scalar, T: Transformation<S>> Transformation<S> for &'l T {
#[inline]
fn transform_point(&self, p: Point<S>) -> Point<S> {
(*self).transform_point(p)
}
#[inline]
fn transform_vector(&self, v: Vector<S>) -> Vector<S> {
(*self).transform_vector(v)
}
}
}