#![doc(html_logo_url = "https://nical.github.io/lyon-doc/lyon-logo.svg")]
#![deny(bare_trait_objects)]
#![deny(unconditional_recursion)]
#![allow(clippy::match_like_matches_macro)]
#![no_std]
extern crate alloc;
#[cfg(any(test, feature = "std"))]
extern crate std;
pub use lyon_geom as geom;
#[cfg(feature = "serialization")]
#[macro_use]
pub extern crate serde;
pub mod builder;
pub mod commands;
mod events;
pub mod iterator;
pub mod path;
pub mod path_buffer;
pub mod polygon;
#[doc(hidden)]
pub mod private;
#[doc(inline)]
pub use crate::commands::{PathCommands, PathCommandsSlice};
pub use crate::events::*;
pub use crate::geom::ArcFlags;
#[doc(inline)]
pub use crate::path::{Path, PathSlice};
#[doc(inline)]
pub use crate::path_buffer::{PathBuffer, PathBufferSlice};
#[doc(inline)]
pub use crate::polygon::{IdPolygon, Polygon};
use math::Point;
use core::fmt;
use core::u32;
pub mod traits {
pub use crate::builder::Build;
pub use crate::builder::PathBuilder;
pub use crate::builder::SvgPathBuilder;
pub use crate::iterator::PathIterator;
}
pub mod math {
use crate::geom::euclid;
pub type Point = euclid::default::Point2D<f32>;
pub type Vector = euclid::default::Vector2D<f32>;
pub type Size = euclid::default::Size2D<f32>;
pub type Box2D = euclid::default::Box2D<f32>;
pub type Transform = euclid::default::Transform2D<f32>;
pub type Rotation = euclid::default::Rotation2D<f32>;
pub type Translation = euclid::Translation2D<f32, euclid::UnknownUnit, euclid::UnknownUnit>;
pub type Scale = euclid::default::Scale<f32>;
pub type Angle = euclid::Angle<f32>;
#[inline]
pub fn vector(x: f32, y: f32) -> Vector {
Vector::new(x, y)
}
#[inline]
pub fn point(x: f32, y: f32) -> Point {
Point::new(x, y)
}
#[inline]
pub fn size(w: f32, h: f32) -> Size {
Size::new(w, h)
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum LineCap {
Butt,
Square,
Round,
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum LineJoin {
Miter,
MiterClip,
Round,
Bevel,
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum Side {
Positive,
Negative,
}
impl Side {
#[inline]
pub fn opposite(self) -> Self {
match self {
Side::Positive => Side::Negative,
Side::Negative => Side::Positive,
}
}
#[inline]
pub fn is_positive(self) -> bool {
self == Side::Positive
}
#[inline]
pub fn is_negative(self) -> bool {
self == Side::Negative
}
#[inline]
pub fn to_f32(self) -> f32 {
match self {
Side::Positive => 1.0,
Side::Negative => -1.0,
}
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum FillRule {
EvenOdd,
NonZero,
}
impl FillRule {
#[inline]
pub fn is_in(&self, winding_number: i16) -> bool {
match *self {
FillRule::EvenOdd => winding_number % 2 != 0,
FillRule::NonZero => winding_number != 0,
}
}
#[inline]
pub fn is_out(&self, winding_number: i16) -> bool {
!self.is_in(winding_number)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub enum Winding {
Positive,
Negative,
}
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct ControlPointId(pub u32);
impl ControlPointId {
pub const INVALID: Self = ControlPointId(u32::MAX);
pub fn offset(self) -> usize {
self.0 as usize
}
pub fn to_usize(self) -> usize {
self.0 as usize
}
pub fn from_usize(val: usize) -> Self {
ControlPointId(val as u32)
}
}
impl fmt::Debug for ControlPointId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "#{}", self.0)
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct EndpointId(pub u32);
impl EndpointId {
pub const INVALID: Self = EndpointId(u32::MAX);
pub fn offset(self) -> usize {
self.0 as usize
}
pub fn to_usize(self) -> usize {
self.0 as usize
}
pub fn from_usize(val: usize) -> Self {
EndpointId(val as u32)
}
}
impl fmt::Debug for EndpointId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "#{}", self.0)
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serialization", derive(Serialize, Deserialize))]
pub struct EventId(#[doc(hidden)] pub u32);
impl EventId {
pub const INVALID: Self = EventId(core::u32::MAX);
pub fn to_usize(self) -> usize {
self.0 as usize
}
}
pub trait Position {
fn position(&self) -> Point;
}
impl<U> Position for crate::geom::euclid::Point2D<f32, U> {
fn position(&self) -> Point {
self.to_untyped()
}
}
impl<'l, T: Position> Position for &'l T {
fn position(&self) -> Point {
(*self).position()
}
}
impl Position for (f32, f32) {
fn position(&self) -> Point {
Point::new(self.0, self.1)
}
}
impl Position for [f32; 2] {
fn position(&self) -> Point {
Point::new(self[0], self[1])
}
}
impl<'l, T> Position for (Point, T) {
fn position(&self) -> Point {
self.0
}
}
pub trait PositionStore {
fn get_endpoint(&self, id: EndpointId) -> Point;
fn get_control_point(&self, id: ControlPointId) -> Point;
}
impl<'l> PositionStore for (&'l [Point], &'l [Point]) {
fn get_endpoint(&self, id: EndpointId) -> Point {
self.0[id.to_usize()]
}
fn get_control_point(&self, id: ControlPointId) -> Point {
self.1[id.to_usize()]
}
}
pub trait AttributeStore {
fn get(&self, id: EndpointId) -> Attributes;
fn num_attributes(&self) -> usize;
}
impl AttributeStore for () {
fn num_attributes(&self) -> usize {
0
}
fn get(&self, _: EndpointId) -> Attributes {
NO_ATTRIBUTES
}
}
pub struct AttributeSlice<'l> {
data: &'l [f32],
stride: usize,
}
impl<'l> AttributeSlice<'l> {
pub fn new(data: &'l [f32], num_attributes: usize) -> Self {
AttributeSlice {
data,
stride: num_attributes,
}
}
}
impl<'l> AttributeStore for AttributeSlice<'l> {
fn get(&self, id: EndpointId) -> Attributes {
let start = id.to_usize() * self.stride;
let end = start + self.stride;
&self.data[start..end]
}
fn num_attributes(&self) -> usize {
self.stride
}
}
pub type AttributeIndex = usize;
pub type Attributes<'l> = &'l [f32];
pub const NO_ATTRIBUTES: Attributes<'static> = &[];