moon_zeno

A low level 2D rasterization library

moon add Milky2018/moon_zeno@0.1.3
Download zip
Author
Version
0.1.3
License
Apache-2.0
Last updated
2 months ago
Downloads
30K
README

#Milky2018/moon_zeno

A low level 2D rasterization library with support for rendering paths of various styles into alpha or subpixel masks.

#What You Get

  • SVG path parsing (String implements PathData)
  • Path evaluation: length, bounds, apply (fill/stroke + optional Transform)
  • Rendering: Mask (Format::Alpha / Format::Subpixel) and HitTest
  • Styles: Fill, Stroke, Style, Join, Cap
  • Traversal helpers: Vertices, Walk

The intended public surface is defined by src/pkg.generated.mbti and is kept aligned with zeno-reference/src/lib.rs re-exports.

#PathBuilder Notes

Upstream zeno exposes rel_*, arc_to, and add_* as default methods on the PathBuilder trait. MoonBit traits don't support default method bodies, so this port keeps PathBuilder as a minimal sink interface and provides the defaults as public helper functions:

  • rel_move_to, rel_line_to, rel_quad_to, rel_curve_to, rel_arc_to
  • arc_to
  • add_rect, add_round_rect, add_ellipse, add_circle

This means custom sinks only need to implement: current_point, move_to, line_to, quad_to, curve_to, close.

#PathData Notes

Besides String and Array[Command], this port also provides:

  • pub impl PathData for (Array[Point], Array[Verb])

which matches upstream’s common point+verb representation.

#Examples

// SVG path data works directly because `String` implements `PathData`.
let svg : String = "M0,0 L3,4 Z"
let len = length(svg, None)

// Point+verb lists also implement `PathData`.
let data = (
[Point::new(1.0, 1.0), Point::new(6.0, 1.0), Point::new(3.5, 6.0)],
[Verb::MoveTo, Verb::LineTo, Verb::LineTo, Verb::Close],
)

let (buf, placement) = Mask::new(data)
.style(Style::Fill(Fill::NonZero))
.size(8U, 8U)
.render()

// `Array[Command]` is both a `PathData` and a `PathBuilder` sink.
let cmds : Array[Command] = []
add_rect(cmds, Point::new(1.0, 2.0), 3.0, 4.0)

#Development

  • moon info && moon fmt
  • moon check
  • moon test

#
PathBuilder

pub(open) trait PathBuilder {
current_point(Self) -> Vector
move_to(Self, Vector) -> Unit
line_to(Self, Vector) -> Unit
quad_to(Self, Vector, Vector) -> Unit
curve_to(Self, Vector, Vector, Vector) -> Unit
close(Self) -> Unit
}

Path builder sink interface.

Ported from upstream zeno/src/path_builder.rs (Apache-2.0 OR MIT).

#
PathData

pub(open) trait PathData {
commands(Self) -> Iter[Command]
copy_to(Self, &PathBuilder) -> Unit
}

Path data abstraction.

Ported from upstream zeno/src/path_data.rs (Apache-2.0 OR MIT).
impl PathData for String

#
Angle

type Angle

Represents an angle in radians (constructors provided for common units).

Ported from upstream zeno/src/geometry.rs::Angle.

#
Angle::from_degrees

fn Angle::from_degrees(degrees : Double) -> Angle

#
Angle::from_gradians

fn Angle::from_gradians(gradians : Double) -> Angle

#
Angle::from_radians

fn Angle::from_radians(radians : Double) -> Angle

#
Angle::from_turns

fn Angle::from_turns(turns : Double) -> Angle

#
Angle::to_degrees

fn Angle::to_degrees(self : Angle) -> Double

#
Angle::to_radians

fn Angle::to_radians(self : Angle) -> Double

#
Angle::zero

fn Angle::zero() -> Angle

#
ArcSize

pub(all) enum ArcSize {
Small
Large
}

Arc size flag (SVG style).

Ported from upstream zeno/src/path_builder.rs.

#
ArcSweep

pub(all) enum ArcSweep {
Positive
Negative
}

Arc sweep flag (SVG style).

Ported from upstream zeno/src/path_builder.rs.

#
Bounds

pub struct Bounds {
min : Vector
max : Vector
}

#
Bounds::add_point

fn Bounds::add_point(self : Bounds, p : Vector) -> Unit

#
Bounds::contains

fn Bounds::contains(self : Bounds, p : Vector) -> Bool

#
Bounds::default

fn Bounds::default() -> Bounds

#
Bounds::from_points

fn Bounds::from_points(points : Array[Vector]) -> Bounds

#
Bounds::height

fn Bounds::height(self : Bounds) -> Double

#
Bounds::is_empty

fn Bounds::is_empty(self : Bounds) -> Bool

#
Bounds::new

fn Bounds::new(min : Vector, max : Vector) -> Bounds

#
Bounds::width

fn Bounds::width(self : Bounds) -> Double

#
Cap

pub(all) enum Cap {
Butt
Square
Round
}

#
Command

pub(all) enum Command {
MoveTo(Vector)
LineTo(Vector)
QuadTo(Vector, Vector)
CurveTo(Vector, Vector, Vector)
Close
}

Path commands.

Ported from upstream zeno/src/command.rs (Apache-2.0 OR MIT).

#
Command::transform

fn Command::transform(self : Command, transform : Transform) -> Command

#
Command::verb

fn Command::verb(self : Command) -> Verb

Returns the associated verb for the command.

#
Fill

pub(all) enum Fill {
NonZero
EvenOdd
}

Path styles.

Ported from upstream zeno/src/style.rs (Apache-2.0 OR MIT).

#
Format

pub(all) enum Format {
Alpha
Subpixel
CustomSubpixel(Array[Double])
}

Mask generator (subset).

Ported from upstream zeno/src/mask.rs (Apache-2.0 OR MIT).

#
Format::buffer_size

fn Format::buffer_size(self : Format, width : UInt, height : UInt) -> Int

#
Format::default

fn Format::default() -> Format

#
Format::subpixel_bgra

fn Format::subpixel_bgra() -> Format

#
HitTest

type HitTest

Builder for configuring and executing a hit test.

#
HitTest::fill

fn HitTest::fill(self : HitTest, fill : Fill) -> HitTest

#
HitTest::hit

fn HitTest::hit(self : HitTest, point : Vector) -> Bool

#
HitTest::new

fn HitTest::new(data : &PathData) -> HitTest

#
HitTest::stroke

fn HitTest::stroke(self : HitTest, stroke : Stroke) -> HitTest

#
HitTest::style

fn HitTest::style(self : HitTest, style : Style) -> HitTest

#
HitTest::threshold

fn HitTest::threshold(self : HitTest, threshold : Int) -> HitTest

#
HitTest::transform

fn HitTest::transform(self : HitTest, transform : Transform?) -> HitTest

#
HitTest::with_scratch

fn HitTest::with_scratch(data : &PathData, scratch : Ref[Scratch]) -> HitTest

#
Join

pub(all) enum Join {
Bevel
Miter
Round
}

#
Mask

type Mask

Builder for configuring and rendering a mask (alpha subset).

Ported from upstream zeno/src/mask.rs (Apache-2.0 OR MIT).

#
Mask::fill

fn Mask::fill(self : Mask, fill : Fill) -> Mask

Convenience wrapper for .style(Style::Fill(fill)).

#
Mask::format

fn Mask::format(self : Mask, format : Format) -> Mask

#
Mask::inspect

fn Mask::inspect(self : Mask, f : (Format, UInt, UInt) -> Unit) -> Mask

#
Mask::new

fn Mask::new(data : &PathData) -> Mask

#
Mask::offset

fn Mask::offset(self : Mask, offset : Vector) -> Mask

#
Mask::origin

fn Mask::origin(self : Mask, origin : Origin) -> Mask

#
Mask::render

fn Mask::render(self : Mask) -> (Array[Byte], Placement)

Renders the mask into a newly allocated buffer.

#
Mask::render_into

fn Mask::render_into(self : Mask, buffer : Array[Byte], pitch? : Int) -> Placement

Renders the mask into a target buffer (tightly packed; alpha only for now).

#
Mask::render_offset

fn Mask::render_offset(self : Mask, offset : Vector) -> Mask

#
Mask::size

fn Mask::size(self : Mask, width : UInt, height : UInt) -> Mask

#
Mask::stroke

fn Mask::stroke(self : Mask, stroke : Stroke) -> Mask

Convenience wrapper for .style(Style::Stroke(stroke)).

#
Mask::style

fn Mask::style(self : Mask, style : Style) -> Mask

#
Mask::transform

fn Mask::transform(self : Mask, transform : Transform?) -> Mask

#
Mask::with_scratch

fn Mask::with_scratch(data : &PathData, scratch : Ref[Scratch]) -> Mask

#
Origin

pub(all) enum Origin {
TopLeft
BottomLeft
}

Bounds, origin and placement.

Ported from upstream zeno/src/geometry.rs (Apache-2.0 OR MIT).

#
Origin::default

fn Origin::default() -> Origin

#
Placement

pub(all) struct Placement {
left : Int
top : Int
width : UInt
height : UInt
}

#
Placement::compute

fn Placement::compute(origin : Origin, offset : Vector, bounds : Bounds) -> (Vector, Placement)

#
Scratch

type Scratch

Context for reusing dynamic memory allocations.

Ported from upstream zeno/src/scratch.rs (Apache-2.0 OR MIT).

NOTE: This is currently a minimal subset: it only stores the heap raster storage used by the rasterizer.

#
Scratch::apply

fn Scratch::apply(self : Scratch, data : &PathData, style : Style, transform : Transform?, sink : &PathBuilder) -> Fill

Applies the style and transform to the path and emits the result to the sink.

This is a thin wrapper that exists to mirror upstream Scratch::apply.

#
Scratch::bounds

fn Scratch::bounds(self : Scratch, data : &PathData, style : Style, transform : Transform?) -> Bounds

Computes the bounding box of the path.

Mirrors upstream Scratch::bounds (fill-only accurate until we port stroke).

#
Scratch::default

fn Scratch::default() -> Scratch

#
Scratch::new

fn Scratch::new() -> Scratch

#
Stroke

pub struct Stroke {
width : Double
join : Join
miter_limit : Double
start_cap : Cap
end_cap : Cap
dashes : Array[Double]
offset : Double
scale : Bool
}

#
Stroke::cap

fn Stroke::cap(self : Stroke, cap : Cap) -> Stroke

#
Stroke::caps

fn Stroke::caps(self : Stroke, start : Cap, end : Cap) -> Stroke

#
Stroke::dash

fn Stroke::dash(self : Stroke, dashes : Array[Double], offset : Double) -> Stroke

#
Stroke::default

fn Stroke::default() -> Stroke

#
Stroke::join

fn Stroke::join(self : Stroke, join : Join) -> Stroke

#
Stroke::miter_limit

fn Stroke::miter_limit(self : Stroke, limit : Double) -> Stroke

#
Stroke::new

fn Stroke::new(width : Double) -> Stroke

#
Stroke::scale

fn Stroke::scale(self : Stroke, scale : Bool) -> Stroke

#
Stroke::width

fn Stroke::width(self : Stroke, width : Double) -> Stroke

#
Style

pub(all) enum Style {
Fill(Fill)
Stroke(Stroke)
}

#
Style::default

fn Style::default() -> Style

#
Style::is_stroke

fn Style::is_stroke(self : Style) -> Bool

#
Transform

pub struct Transform {
xx : Double
xy : Double
yx : Double
yy : Double
x : Double
y : Double
}

2D affine transform.

Ported from upstream zeno/src/geometry.rs (Apache-2.0 OR MIT).

#
Transform::determinant

fn Transform::determinant(self : Transform) -> Double

#
Transform::identity

fn Transform::identity() -> Transform

#
Transform::invert

fn Transform::invert(self : Transform) -> Transform?

#
Transform::new

fn Transform::new(xx : Double, xy : Double, yx : Double, yy : Double, x : Double, y : Double) -> Transform

#
Transform::pre_rotate

fn Transform::pre_rotate(self : Transform, angle : Angle) -> Transform

Returns a new transform that represents a rotation followed by this transform.

#
Transform::pre_scale

fn Transform::pre_scale(self : Transform, x : Double, y : Double) -> Transform

Returns a new transform that represents a scale followed by this transform.

#
Transform::pre_translate

fn Transform::pre_translate(self : Transform, x : Double, y : Double) -> Transform

Returns a new transform that represents a translation followed by this transform.

#
Transform::rotation

fn Transform::rotation(angle : Angle) -> Transform

#
Transform::rotation_about

fn Transform::rotation_about(point : Vector, angle : Angle) -> Transform

#
Transform::scale

fn Transform::scale(x : Double, y : Double) -> Transform

#
Transform::skew

fn Transform::skew(x : Angle, y : Angle) -> Transform

#
Transform::then

fn Transform::then(self : Transform, other : Transform) -> Transform

Returns a new transform that represents the application of this transform followed by other.

#
Transform::then_rotate

fn Transform::then_rotate(self : Transform, angle : Angle) -> Transform

Returns a new transform that represents this transform followed by a rotation.

#
Transform::then_scale

fn Transform::then_scale(self : Transform, x : Double, y : Double) -> Transform

Returns a new transform that represents this transform followed by a scale.

#
Transform::then_translate

fn Transform::then_translate(self : Transform, x : Double, y : Double) -> Transform

Returns a new transform that represents this transform followed by a translation.

#
Transform::transform_point

fn Transform::transform_point(self : Transform, point : Vector) -> Vector

#
Transform::transform_vector

fn Transform::transform_vector(self : Transform, vector : Vector) -> Vector

#
Transform::translate

fn Transform::translate(x : Double, y : Double) -> Transform

#
Transform::translation

fn Transform::translation(x : Double, y : Double) -> Transform

#
Vector

#alias(Point)
pub struct Vector {
x : Double
y : Double
}

Two dimensional vector.
impl Add for Vector
impl Div for Vector
impl Mul for Vector
impl Neg for Vector
impl Sub for Vector

#
Vector::angle_to

fn Vector::angle_to(self : Vector, other : Vector) -> Angle

Returns the angle to the specified vector.

#
Vector::ceil

fn Vector::ceil(self : Vector) -> Vector

#
Vector::cross

fn Vector::cross(self : Vector, other : Vector) -> Double

#
Vector::distance_to

fn Vector::distance_to(self : Vector, other : Vector) -> Double

#
Vector::div_scalar

fn Vector::div_scalar(self : Vector, s : Double) -> Vector

#
Vector::dot

fn Vector::dot(self : Vector, other : Vector) -> Double

#
Vector::floor

fn Vector::floor(self : Vector) -> Vector

#
Vector::length

fn Vector::length(self : Vector) -> Double

#
Vector::length_squared

fn Vector::length_squared(self : Vector) -> Double

#
Vector::nearly_eq

fn Vector::nearly_eq(self : Vector, other : Vector) -> Bool

Equivalent to upstream Vector::nearly_eq (uses f32 epsilon).

#
Vector::nearly_eq_by

fn Vector::nearly_eq_by(self : Vector, other : Vector, epsilon : Double) -> Bool

#
Vector::new

fn Vector::new(x : Double, y : Double) -> Vector

#
Vector::normalize

fn Vector::normalize(self : Vector) -> Vector

#
Vector::scale

fn Vector::scale(self : Vector, s : Double) -> Vector

#
Vector::x

fn Vector::x(self : Vector) -> Double

#
Vector::y

fn Vector::y(self : Vector) -> Double

#
Vector::zero

fn Vector::zero() -> Vector

#
Verb

pub(all) enum Verb {
MoveTo
LineTo
QuadTo
CurveTo
Close
}

Minimal zeno port: path verbs.

Ported from upstream zeno crate (Apache-2.0 OR MIT).

#
Vertex

pub(all) enum Vertex {
Start(Vector, Vector)
Middle(Vector, Vector, Vector)
End(Vector, Vector, Bool)
}

A vertex of a path.

#
Vertices

type Vertices

Iterator over the vertices of a path.

#
Vertices::new

fn Vertices::new(data : &PathData) -> Vertices

#
Vertices::next

fn Vertices::next(self : Vertices) -> Vertex?

#
Vertices::with_transform

fn Vertices::with_transform(data : &PathData, transform : Transform) -> Vertices

#
Walk

type Walk

Iterator-like type that walks along a path by arbitrary steps.

#
Walk::new

fn Walk::new(data : &PathData) -> Walk

#
Walk::remaining

fn Walk::remaining(self : Walk) -> Double

#
Walk::step

fn Walk::step(self : Walk, distance : Double) -> (Vector, Vector)?

Steps by the specified distance.

#
Walk::with_transform

fn Walk::with_transform(data : &PathData, transform : Transform) -> Walk

#
add_circle

fn add_circle(sink : &PathBuilder, center : Vector, r : Double) -> Unit

#
add_ellipse

fn add_ellipse(sink : &PathBuilder, center : Vector, rx : Double, ry : Double) -> Unit

#
add_rect

fn add_rect(sink : &PathBuilder, xy : Vector, w : Double, h : Double) -> Unit

#
add_round_rect

fn add_round_rect(sink : &PathBuilder, xy : Vector, w : Double, h : Double, rx0 : Double, ry0 : Double) -> Unit

#
apply

fn apply(data : &PathData, style : Style, transform : Transform?, sink : &PathBuilder) -> Fill

Applies the style and transform to the path and emits the result to the sink.

#
arc_to

fn arc_to(sink : &PathBuilder, rx : Double, ry : Double, angle : Angle, size : ArcSize, sweep : ArcSweep, to : Vector) -> Unit

#
bounds

fn bounds(data : &PathData, style : Style, transform : Transform?) -> Bounds

Computes the bounding box of the path (style/transform aware; fill-only accurate for now).

#
length

fn length(data : &PathData, transform : Transform?) -> Double

Computes the total length of the path.

Ported from upstream zeno/src/path_data.rs::length.

#
rel_arc_to

fn rel_arc_to(sink : &PathBuilder, rx : Double, ry : Double, angle : Angle, size : ArcSize, sweep : ArcSweep, to : Vector) -> Unit

#
rel_curve_to

fn rel_curve_to(sink : &PathBuilder, c1 : Vector, c2 : Vector, to : Vector) -> Unit

#
rel_line_to

fn rel_line_to(sink : &PathBuilder, to : Vector) -> Unit

#
rel_move_to

fn rel_move_to(sink : &PathBuilder, to : Vector) -> Unit

Convenience operations built on top of the core PathBuilder methods.

Upstream Rust exposes these as default trait methods on PathBuilder. MoonBit traits do not support default method bodies, so we provide them as free functions.

#
rel_quad_to

fn rel_quad_to(sink : &PathBuilder, c : Vector, to : Vector) -> Unit

#
validate_svg

fn validate_svg(svg : String) -> Result[Unit, Int]

Validate an SVG path string and return the first invalid position.