Struct BezPath
pub struct BezPath(/* private fields */);Expand description
A Bézier path.
These docs assume basic familiarity with Bézier curves; for an introduction, see Pomax’s wonderful A Primer on Bézier Curves.
This path can contain lines, quadratics (QuadBez) and cubics
(CubicBez), and may contain multiple subpaths.
§Elements and Segments
A Bézier path can be represented in terms of either ‘elements’ (PathEl)
or ‘segments’ (PathSeg). Elements map closely to how Béziers are
generally used in PostScript-style drawing APIs; they can be thought of as
instructions for drawing the path. Segments more directly describe the
path itself, with each segment being an independent line or curve.
These different representations are useful in different contexts. For tasks like drawing, elements are a natural fit, but when doing hit-testing or subdividing, we need to have access to the segments.
Conceptually, a BezPath contains zero or more subpaths. Each subpath
always begins with a MoveTo, then has zero or more LineTo, QuadTo,
and CurveTo elements, and optionally ends with a ClosePath.
Internally, a BezPath is a list of PathEls; as such it implements
FromIterator<PathEl> and Extend<PathEl>:
use kurbo::{BezPath, Rect, Shape, Vec2};
let accuracy = 0.1;
let rect = Rect::from_origin_size((0., 0.,), (10., 10.));
// these are equivalent
let path1 = rect.to_path(accuracy);
let path2: BezPath = rect.path_elements(accuracy).collect();
// extend a path with another path:
let mut path = rect.to_path(accuracy);
let shifted_rect = rect + Vec2::new(5.0, 10.0);
path.extend(shifted_rect.to_path(accuracy));You can iterate the elements of a BezPath with the iter method,
and the segments with the segments method:
use kurbo::{BezPath, Line, PathEl, PathSeg, Point, Rect, Shape};
let accuracy = 0.1;
let rect = Rect::from_origin_size((0., 0.,), (10., 10.));
// these are equivalent
let path = rect.to_path(accuracy);
let first_el = PathEl::MoveTo(Point::ZERO);
let first_seg = PathSeg::Line(Line::new((0., 0.), (10., 0.)));
assert_eq!(path.iter().next(), Some(first_el));
assert_eq!(path.segments().next(), Some(first_seg));In addition, if you have some other type that implements
Iterator<Item=PathEl>, you can adapt that to an iterator of segments with
the segments free function.
§Advanced functionality
In addition to the basic API, there are several useful pieces of advanced
functionality available on BezPath:
flattendoes Bézier flattening, converting a curve to a series of line segmentsintersect_linecomputes intersections of a path with a line, useful for things like subdividing
Implementations§
§impl BezPath
impl BezPath
pub fn with_capacity(capacity: usize) -> BezPath
pub fn with_capacity(capacity: usize) -> BezPath
Create a new path with the specified capacity.
This can be useful if you already know how many path elements the path will consist of, to prevent reallocations.
pub fn from_vec(v: Vec<PathEl>) -> BezPath
pub fn from_vec(v: Vec<PathEl>) -> BezPath
Create a path from a vector of path elements.
BezPath also implements FromIterator<PathEl>, so it works with collect:
// a very contrived example:
use kurbo::{BezPath, PathEl};
let path = BezPath::new();
let as_vec: Vec<PathEl> = path.into_iter().collect();
let back_to_path: BezPath = as_vec.into_iter().collect();pub fn pop(&mut self) -> Option<PathEl>
pub fn pop(&mut self) -> Option<PathEl>
Removes the last PathEl from the path and returns it, or None if the path is empty.
pub fn line_to<P>(&mut self, p: P)
pub fn line_to<P>(&mut self, p: P)
Push a “line to” element onto the path.
Will panic with a debug assert when the path is empty and there is no “move to” element on the path.
If line_to is called immediately after close_path then the current
subpath starts at the initial point of the previous subpath.
pub fn quad_to<P>(&mut self, p1: P, p2: P)
pub fn quad_to<P>(&mut self, p1: P, p2: P)
Push a “quad to” element onto the path.
Will panic with a debug assert when the path is empty and there is no “move to” element on the path.
If quad_to is called immediately after close_path then the current
subpath starts at the initial point of the previous subpath.
pub fn curve_to<P>(&mut self, p1: P, p2: P, p3: P)
pub fn curve_to<P>(&mut self, p1: P, p2: P, p3: P)
Push a “curve to” element onto the path.
Will panic with a debug assert when the path is empty and there is no “move to” element on the path.
If curve_to is called immediately after close_path then the current
subpath starts at the initial point of the previous subpath.
pub fn close_path(&mut self)
pub fn close_path(&mut self)
Push a “close path” element onto the path.
Will panic with a debug assert when the path is empty and there is no “move to” element on the path.
pub fn into_elements(self) -> Vec<PathEl>
pub fn into_elements(self) -> Vec<PathEl>
Consumes the BezPath and returns a vector of PathEls.
pub fn elements(&self) -> &[PathEl]
pub fn elements(&self) -> &[PathEl]
Get the path elements.
For owned elements, see into_elements.
pub fn elements_mut(&mut self) -> &mut [PathEl]
pub fn elements_mut(&mut self) -> &mut [PathEl]
Get the path elements (mut version).
pub fn iter(&self) -> impl Iterator<Item = PathEl> + Clone
pub fn iter(&self) -> impl Iterator<Item = PathEl> + Clone
Returns an iterator over the path’s elements.
pub fn get_seg(&self, ix: usize) -> Option<PathSeg>
pub fn get_seg(&self, ix: usize) -> Option<PathSeg>
Get the segment at the given element index.
If you need to access all segments, segments provides a better
API. This is intended for random access of specific elements, for clients
that require this specifically.
note: This returns the segment that ends at the provided element
index. In effect this means it is 1-indexed: since no segment ends at
the first element (which is presumed to be a MoveTo) get_seg(0) will
always return None.
pub fn apply_affine(&mut self, affine: Affine)
pub fn apply_affine(&mut self, affine: Affine)
Apply an affine transform to the path.
pub fn control_box(&self) -> Rect
pub fn control_box(&self) -> Rect
Returns a rectangle that conservatively encloses the path.
Unlike the bounding_box method, this uses control points directly
rather than computing tight bounds for curve elements.
pub fn current_position(&self) -> Option<Point>
pub fn current_position(&self) -> Option<Point>
Returns current position in the path, if path is not empty.
This is different from calling PathEl::end_point on the last entry of BezPath::elements:
this method handles PathEl::ClosePath,
by finding the first point of our last subpath, hence the time complexity is O(n).
pub fn subpaths(&self) -> impl Iterator<Item = &[PathEl]>
pub fn subpaths(&self) -> impl Iterator<Item = &[PathEl]>
Returns an iterator over the subpaths of this path. See Elements and Segments for more information.
pub fn reverse_subpaths(&self) -> BezPath
pub fn reverse_subpaths(&self) -> BezPath
Returns a new path with the winding direction of all subpaths reversed.
§impl BezPath
impl BezPath
pub fn from_path_segments(segments: impl Iterator<Item = PathSeg>) -> BezPath
pub fn from_path_segments(segments: impl Iterator<Item = PathSeg>) -> BezPath
Create a BezPath with segments corresponding to the sequence of
PathSegs
pub fn to_svg(&self) -> String
pub fn to_svg(&self) -> String
Convert the path to an SVG path string representation.
The current implementation doesn’t take any special care to produce a short string (reducing precision, using relative movement).
pub fn write_to<W>(&self, writer: W) -> Result<(), Error>where
W: Write,
pub fn write_to<W>(&self, writer: W) -> Result<(), Error>where
W: Write,
Write the SVG representation of this path to the provided buffer.
pub fn from_svg(data: &str) -> Result<BezPath, SvgParseError>
pub fn from_svg(data: &str) -> Result<BezPath, SvgParseError>
Try to parse a bezier path from an SVG path element.
This is implemented on a best-effort basis, intended for cases where the user controls the source of paths, and is not intended as a replacement for a general, robust SVG parser.
Trait Implementations§
§impl Extend<PathEl> for BezPath
impl Extend<PathEl> for BezPath
§fn extend<I>(&mut self, iter: I)where
I: IntoIterator<Item = PathEl>,
fn extend<I>(&mut self, iter: I)where
I: IntoIterator<Item = PathEl>,
Add the items from the iterator to this path.
Note that if you’re attempting to make a continuous path, you will generally
want to ensure that the iterator does not contain any MoveTo
or ClosePath elements.
Note especially that many (open) shapes will start with a MoveTo if
you use their path_elements function.
Some shapes have alternatives for this use case, such as Arc::append_iter.
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)§impl FromIterator<PathEl> for BezPath
impl FromIterator<PathEl> for BezPath
§impl<'a> IntoIterator for &'a BezPath
Allow iteration over references to BezPath.
impl<'a> IntoIterator for &'a BezPath
Allow iteration over references to BezPath.
Note: the semantics are slightly different from simply iterating over the
slice, as it returns PathEl items, rather than references.
§impl IntoIterator for BezPath
impl IntoIterator for BezPath
§impl Mul<&BezPath> for TranslateScale
impl Mul<&BezPath> for TranslateScale
§impl Mul<BezPath> for TranslateScale
impl Mul<BezPath> for TranslateScale
§impl Shape for BezPath
impl Shape for BezPath
§type PathElementsIter<'iter> = Copied<Iter<'iter, PathEl>>
type PathElementsIter<'iter> = Copied<Iter<'iter, PathEl>>
path_elements method.§fn path_elements(
&self,
_tolerance: f64,
) -> <BezPath as Shape>::PathElementsIter<'_>
fn path_elements( &self, _tolerance: f64, ) -> <BezPath as Shape>::PathElementsIter<'_>
§fn bounding_box(&self) -> Rect
fn bounding_box(&self) -> Rect
§fn as_path_slice(&self) -> Option<&[PathEl]>
fn as_path_slice(&self) -> Option<&[PathEl]>
§fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> ⓘ
fn path_segments(&self, tolerance: f64) -> Segments<Self::PathElementsIter<'_>> ⓘ
§fn as_rounded_rect(&self) -> Option<RoundedRect>
fn as_rounded_rect(&self) -> Option<RoundedRect>
impl StructuralPartialEq for BezPath
Auto Trait Implementations§
impl Freeze for BezPath
impl RefUnwindSafe for BezPath
impl Send for BezPath
impl Sync for BezPath
impl Unpin for BezPath
impl UnsafeUnpin for BezPath
impl UnwindSafe for BezPath
Blanket Implementations§
§impl<T> AnyEq for T
impl<T> AnyEq for T
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more