Standalone SVG scene graph and renderer
moon add mizchi/svglet svg = "<svg width=\"10\" height=\"10\"><rect x=\"1\" y=\"1\" width=\"8\" height=\"8\" fill=\"red\"/></svg>"
match render_svg_to_image(svg, 16, 16) {
Some(image) => image
None => panic("parse failed")
}let node = rect("r", 2.0, 2.0, 6.0, 6.0)
node.fill = SolidColor(Color::black())
let doc = SVGDocument::new(node)
let image = render_svg_document_to_image(doc, 16, 16)let scene = Scene::new(node)
let image = render_svg_scene_to_image(scene, 16, 16)let image = Image::new(64, 64)
let setter : PixelSetter = { set: fn(x, y, c) { image.set_pixel(x, y, c) } }
let ctx = RenderContext::new(setter, 64, 64)
let doc = SVGDocument::new(rect("r", 0.0, 0.0, 10.0, 10.0))
doc.render(ctx)git submodule update --init --depth 1 wpt
just wpt-svgjust wpt-svg --limit=50pub(all) enum AnimProperty {
TranslateX(Double)
TranslateY(Double)
Translate(Double, Double)
ScaleX(Double)
ScaleY(Double)
Scale(Double, Double)
ScaleUniform(Double)
Rotation(Double)
Opacity(Double)
FillColor(Color)
}pub(all) struct AnimatedSprite {
sheet : SpriteSheet
frames : Array[Int]
current_frame : Int
frame_duration : Double
elapsed : Double
looping : Bool
playing : Bool
}fn AnimatedSprite::from_range(sheet : SpriteSheet, start : Int, end : Int, frame_duration : Double) -> AnimatedSpritefn AnimatedSprite::new(sheet : SpriteSheet, frames : Array[Int], frame_duration : Double) -> AnimatedSpritefn AnimationManager::animate_opacity(self : AnimationManager, target_id : String, opacity : Double, duration : Double, easing : Easing) -> Unitfn AnimationManager::animate_scale(self : AnimationManager, target_id : String, scale : Double, duration : Double, easing : Easing) -> Unitfn AnimationManager::animate_translate(self : AnimationManager, target_id : String, x : Double, y : Double, duration : Double, easing : Easing) -> Unitpub(all) struct BoundingBox {
min_x : Double
min_y : Double
max_x : Double
max_y : Double
}pub(all) struct Camera {
x : Double
y : Double
zoom : Double
viewport_width : Int
viewport_height : Int
}pub(all) struct ClipPath {
id : String
shape : Shape
transform : Transform
clip_rule : FillRule
units : ClipPathUnits
}pub(all) struct ClipRect {
x : Int
y : Int
width : Int
height : Int
}pub(all) struct Color {
r : Int
g : Int
b : Int
a : Int
}pub(all) enum DominantBaseline {
Auto
TextTop
Hanging
Middle
Central
TextBottom
Alphabetic
Ideographic
}pub(all) struct EventManager {
listeners : Map[String, Array[EventListener]]
hovered_node : String?
dragging_node : String?
drag_start_x : Double
drag_start_y : Double
}fn EventManager::dispatch_click(self : EventManager, x : Double, y : Double, button : Int, scene : Scene) -> Unitfn EventManager::dispatch_mouse_down(self : EventManager, x : Double, y : Double, button : Int, scene : Scene) -> Unitfn EventManager::dispatch_mouse_move(self : EventManager, x : Double, y : Double, scene : Scene) -> Unitfn EventManager::dispatch_mouse_up(self : EventManager, x : Double, y : Double, button : Int, scene : Scene) -> Unitfn EventManager::on(self : EventManager, node_id : String, event_type : EventType, handler : EventHandler) -> Unitpub(all) enum Filter {
Blur(Double)
DropShadow(Double, Double, Double, Color)
Brightness(Double)
Contrast(Double)
Grayscale(Double)
Sepia(Double)
HueRotate(Double)
Invert(Double)
Saturate(Double)
ColorMatrix(FixedArray[Double])
}pub(all) struct LinearGradient {
x1 : Double
y1 : Double
x2 : Double
y2 : Double
stops : Array[GradientStop]
spread_method : SpreadMethod
units : GradientUnits
transform : Transform
}fn LinearGradient::new(x1 : Double, y1 : Double, x2 : Double, y2 : Double, stops : Array[GradientStop]) -> LinearGradientpub(all) struct MarkedLine {
points : Array[(Double, Double)]
marker_start : String?
marker_mid : String?
marker_end : String?
}fn MarkedLine::with_markers(points : Array[(Double, Double)], start : String?, mid : String?, end : String?) -> MarkedLinepub(all) struct Marker {
id : String
content : SVGNode
ref_x : Double
ref_y : Double
marker_width : Double
marker_height : Double
orient : MarkerOrient
marker_units : MarkerUnits
view_box : ViewBox?
preserve_aspect_ratio : PreserveAspectRatio
clip_overflow : Bool
}impl Show for MeetOrSlicepub(all) enum Paint {
None
SolidColor(Color)
LinearGrad(LinearGradient)
RadialGrad(RadialGradient)
CurrentColor
PaintServerRef(String, PaintFallback)
}impl Show for PaintOrderItempub(all) struct Particle {
x : Double
y : Double
vx : Double
vy : Double
life : Double
max_life : Double
size : Double
color : Color
active : Bool
}pub(all) struct ParticleEmitter {
x : Double
y : Double
config : EmitterConfig
particles : Array[Particle]
emit_accumulator : Double
active : Bool
}fn ParticleEmitter::new(x : Double, y : Double, config : EmitterConfig, max_particles : Int) -> ParticleEmitterpub(all) enum PathCommand {
MoveTo(Double, Double)
LineTo(Double, Double)
HorizontalLineTo(Double)
VerticalLineTo(Double)
CurveTo(Double, Double, Double, Double, Double, Double)
SmoothCurveTo(Double, Double, Double, Double)
QuadraticCurveTo(Double, Double, Double, Double)
SmoothQuadraticCurveTo(Double, Double)
ArcTo(Double, Double, Double, Bool, Bool, Double, Double)
ClosePath
MoveToRel(Double, Double)
LineToRel(Double, Double)
HorizontalLineToRel(Double)
VerticalLineToRel(Double)
CurveToRel(Double, Double, Double, Double, Double, Double)
SmoothCurveToRel(Double, Double, Double, Double)
QuadraticCurveToRel(Double, Double, Double, Double)
SmoothQuadraticCurveToRel(Double, Double)
ArcToRel(Double, Double, Double, Bool, Bool, Double, Double)
} derive(Debug)pub(all) struct PathFollower {
path : Array[PathCommand]
polyline : Array[(Double, Double)]
lengths : Array[Double]
total_length : Double
progress : Double
loop_anim : Bool
}pub(all) struct Pattern {
id : String
width : Double
height : Double
content : Array[SVGNode]
pattern_units : PatternUnits
pattern_content_units : PatternUnits
transform : Transform
view_box : ViewBox?
preserve_aspect_ratio : PreserveAspectRatio
}fn PixelSetter::with_clip_and_offset(self : PixelSetter, clip : ClipRect, offset_x : Int, offset_y : Int) -> PixelSetterpub(all) struct PointerEvent {
x : Double
y : Double
button : Int
target : String
propagation_stopped : Bool
}pub(all) struct RadialGradient {
cx : Double
cy : Double
fx : Double
fy : Double
r : Double
stops : Array[GradientStop]
spread_method : SpreadMethod
units : GradientUnits
transform : Transform
}fn RadialGradient::color_at(self : RadialGradient, px : Double, py : Double, width : Double, height : Double) -> Colorfn RadialGradient::new(cx : Double, cy : Double, r : Double, stops : Array[GradientStop]) -> RadialGradientpub(all) struct RenderContext {
setter : PixelSetter
width : Int
height : Int
flatness : Double
clip : ClipRect?
text_to_paths : (Int, Double) -> (Array[PathCommand], Double)?
}fn RenderContext::with_clip(setter : PixelSetter, width : Int, height : Int, clip : ClipRect) -> RenderContextfn RenderContext::with_font(setter : PixelSetter, width : Int, height : Int, text_to_paths : (Int, Double) -> (Array[PathCommand], Double)) -> RenderContextpub(all) struct SVGDocument {
root : SVGNode
symbols : SymbolRegistry
clips : ClipPathRegistry
masks : MaskRegistry
patterns : PatternRegistry
gradients : GradientRegistry
markers : MarkerRegistry
}pub(all) struct SVGNode {
id : String
shape : Shape
transform : Transform
view_box : ViewBox?
viewport_width : Double?
viewport_height : Double?
preserve_aspect_ratio : PreserveAspectRatio
preserve_aspect_ratio_is_set : Bool
fill : Paint
fill_is_set : Bool
color : Color?
color_is_set : Bool
paint_order : PaintOrder
fill_rule : FillRule
fill_opacity : Double
stroke : StrokeStyle
stroke_paint_is_set : Bool
stroke_width_is_set : Bool
stroke_opacity : Double
opacity : Double
marker_start : String?
marker_start_is_set : Bool
marker_mid : String?
marker_mid_is_set : Bool
marker_end : String?
marker_end_is_set : Bool
z_index : Int
node_dirty : Bool
prev_bounds : BoundingBox?
filters : Array[Filter]
mask_id : String?
clip_path_id : String?
clip_overflow : Bool
children : Array[SVGNode]
}fn Scene::render_with_viewbox(self : Scene, ctx : RenderContext, viewbox : ViewBox, preserve_aspect_ratio : PreserveAspectRatio) -> Unitfn Scene::render_with_viewbox_and_camera(self : Scene, ctx : RenderContext, viewbox : ViewBox, preserve_aspect_ratio : PreserveAspectRatio, camera : Camera) -> Unitpub(all) enum Shape {
Rect(x~ : Double, y~ : Double, width~ : Double, height~ : Double, rx~ : Double, ry~ : Double)
Circle(cx~ : Double, cy~ : Double, r~ : Double)
Ellipse(cx~ : Double, cy~ : Double, rx~ : Double, ry~ : Double)
Line(x1~ : Double, y1~ : Double, x2~ : Double, y2~ : Double)
Polyline(points~ : Array[(Double, Double)])
Polygon(points~ : Array[(Double, Double)])
Path(commands~ : Array[PathCommand])
Text(x~ : Double, y~ : Double, text~ : String, font_size~ : Double)
Image(x~ : Double, y~ : Double, width~ : Double, height~ : Double, href~ : String)
Group
} derive(Debug)pub(all) struct SimpleRNG {
state : Int
}pub(all) struct SpriteSheet {
image : Image
tile_width : Int
tile_height : Int
columns : Int
rows : Int
}pub(all) struct Symbol {
id : String
content : SVGNode
view_box : ViewBox?
width : Double?
height : Double?
preserve_aspect_ratio : PreserveAspectRatio
display_none : Bool
}pub(all) struct TextBlock {
spans : Array[TextSpan]
x : Double
y : Double
style : TextStyle
inline_size : Double?
text_overflow : TextOverflow
}impl Show for TextDecorationpub(all) struct TextDecorationFull {
line : TextDecoration
style : TextDecorationStyle
color : Color?
thickness : Double?
}impl Show for TextDecorationStyleimpl Show for TextOrientationimpl Show for TextOverflowpub(all) struct TextSpan {
text : String
x : Double?
y : Double?
dx : Double
dy : Double
style : TextStyle?
}pub(all) struct TextStyle {
font_family : String
font_size : Double
font_weight : FontWeight
font_style : FontStyle
text_anchor : TextAnchor
dominant_baseline : DominantBaseline
text_decoration : TextDecoration
letter_spacing : Double
word_spacing : Double
line_height : Double
writing_mode : WritingMode
text_orientation : TextOrientation
white_space : WhiteSpace
paint_order : PaintOrder
}pub(all) struct Transform {
a : Double
b : Double
c : Double
d : Double
e : Double
f : Double
}pub(all) struct Tween {
target_id : String
property : AnimProperty
start_value : AnimProperty
duration : Double
elapsed : Double
easing : Easing
started : Bool
completed : Bool
}fn Tween::new(target_id : String, property : AnimProperty, duration : Double, easing : Easing) -> Tweenpub(all) struct UseElement {
href : String
x : Double
y : Double
width : Double?
height : Double?
transform : Transform
}fn UseElement::with_size(href : String, x : Double, y : Double, width : Double, height : Double) -> UseElementpub(all) struct ViewBox {
min_x : Double
min_y : Double
width : Double
height : Double
}fn ViewBox::get_transform(self : ViewBox, viewport_width : Double, viewport_height : Double, preserve_aspect_ratio : PreserveAspectRatio) -> Transformimpl Show for WhiteSpaceimpl Show for WritingModefn apply_text_overflow(line : String, max_width : Double, char_width : Double, overflow : TextOverflow) -> Stringfn collide_circle_circle(cx1 : Double, cy1 : Double, r1 : Double, cx2 : Double, cy2 : Double, r2 : Double) -> Boolfn collide_circle_rect(cx : Double, cy : Double, r : Double, rx : Double, ry : Double, rw : Double, rh : Double) -> Boolfn collide_rect_rect(x1 : Double, y1 : Double, w1 : Double, h1 : Double, x2 : Double, y2 : Double, w2 : Double, h2 : Double) -> Boolfn degrees_to_radians(degrees : Double) -> Doublefn hue_rotate_matrix(angle_degrees : Double) -> FixedArray[Double]fn luminance_to_alpha_matrix() -> FixedArray[Double]fn path_to_polylines(commands : Array[PathCommand], flatness : Double) -> Array[Array[(Double, Double)]]fn radians_to_degrees(radians : Double) -> Doublefn raster_circle_radial_gradient(cx : Int, cy : Int, r : Int, grad : RadialGradient, opacity : Double, setter : PixelSetter) -> Unitfn raster_ellipse_fill(cx : Int, cy : Int, rx : Int, ry : Int, color : Color, setter : PixelSetter) -> Unitfn raster_ellipse_radial_gradient(cx : Int, cy : Int, rx : Int, ry : Int, grad : RadialGradient, opacity : Double, setter : PixelSetter) -> Unitfn raster_ellipse_stroke(cx : Int, cy : Int, rx : Int, ry : Int, color : Color, setter : PixelSetter) -> Unitfn raster_line_dashed(x0 : Int, y0 : Int, x1 : Int, y1 : Int, color : Color, dasharray : Array[Double], dashoffset : Double, setter : PixelSetter) -> Unitfn raster_path(commands : Array[PathCommand], fill_color : Color?, stroke_color : Color?, flatness : Double, setter : PixelSetter) -> Unitfn raster_polygon_fill_rule(points : Array[(Int, Int)], color : Color, rule : FillRule, setter : PixelSetter) -> Unitfn raster_polygons_fill_rule(polygons : Array[Array[(Int, Int)]], color : Color, rule : FillRule, setter : PixelSetter) -> Unitfn raster_polyline_dashed(points : Array[(Int, Int)], color : Color, dasharray : Array[Double], dashoffset : Double, setter : PixelSetter) -> Unitfn raster_rect_fill(x : Int, y : Int, w : Int, h : Int, color : Color, setter : PixelSetter) -> Unitfn raster_rect_gradient(x : Int, y : Int, w : Int, h : Int, grad : LinearGradient, opacity : Double, setter : PixelSetter) -> Unitfn raster_rect_radial_gradient(x : Int, y : Int, w : Int, h : Int, grad : RadialGradient, opacity : Double, setter : PixelSetter) -> Unitfn raster_rect_stroke(x : Int, y : Int, w : Int, h : Int, color : Color, setter : PixelSetter) -> Unitfn raster_rect_stroke_thick(x : Int, y : Int, w : Int, h : Int, stroke_w : Int, color : Color, setter : PixelSetter) -> Unitfn raster_rounded_rect_fill(x : Int, y : Int, w : Int, h : Int, rx : Int, ry : Int, color : Color, setter : PixelSetter) -> Unitfn raster_rounded_rect_stroke(x : Int, y : Int, w : Int, h : Int, rx : Int, ry : Int, color : Color, setter : PixelSetter) -> Unitfn raster_rounded_rect_stroke_thick(x : Int, y : Int, w : Int, h : Int, rx : Int, ry : Int, stroke_w : Int, color : Color, setter : PixelSetter) -> Unitfn raster_text(x : Int, y : Int, text : String, font_size : Int, color : Color, setter : PixelSetter) -> Unitfn raster_thick_line(x0 : Int, y0 : Int, x1 : Int, y1 : Int, width : Int, color : Color, setter : PixelSetter) -> Unitfn render_path_commands_to_image(commands : Array[PathCommand], width : Int, height : Int, fill_color : Color, transform? : Array[Double]) -> Imagefn saturate_matrix(factor : Double) -> FixedArray[Double]Standalone SVG scene graph and renderer