Standalone SVG scene graph and renderer
Dependencies
moon add Milky2018/svg| 0.3.x API | 0.4.0 replacement | Notes |
|---|---|---|
| parse_svg(source) | parse_svg_document(source).map(fn(document) { document.root() }) | Use the document result when resources are needed. |
| parse_svg_document(source) | Unchanged | Returns SVGDocument?. |
| render_svg(source, width, height, options) | Unchanged | Returns RenderResult with an owned image and diagnostics. |
| render_svg_to_image(source, width, height) | Unchanged | Remains the simple Image? convenience. |
| render_svg_to_image_with_resolver(...) | render_svg(source, width, height, RenderOptions::with_image_resolver(resolver)) | Read .image and inspect .diagnostics; parse failure is reported diagnostically. |
| render_svg_document_to_image(...) | render_svg_document(document, width, height, RenderOptions::default()).image | Use the structured result when diagnostics matter. |
| render_svg_document_to_image_with_resolver(...) | render_svg_document(document, width, height, RenderOptions::with_image_resolver(resolver)).image | Resolver configuration is no longer a separate function family. |
| render_svg_node_to_image* | render_svg_document(SVGDocument::new(node), width, height, options).image | Register referenced resources on the document before rendering. |
| render_svg_scene_to_image* and Scene | No direct replacement | Migrate authored content to SVGDocument and SVGNode. |
| PixelSetter, RenderContext, context-driven .render, and public raster_* functions | No direct replacement | The renderer owns its target image; use the rendering facade. |
| render_path_commands_to_image(...) | Unchanged | Remains the expert direct-path entry point. |
///|
test "README: render SVG markup" {
let source = "<svg width=\"10\" height=\"10\"><rect x=\"1\" y=\"1\" width=\"8\" height=\"8\" fill=\"red\"/></svg>"
let image = render_svg_to_image(source, 16, 16)
assert_true(image is Some(_))
}///|
test "README: parse and render a document" {
let source = "<svg width=\"4\" height=\"4\"><circle cx=\"2\" cy=\"2\" r=\"2\"/></svg>"
match parse_svg_document(source) {
Some(document) => {
let result = render_svg_document(document, 4, 4, RenderOptions::default())
assert_eq(result.image.width(), 4)
}
None => fail("expected a valid SVG document")
}
}///|
test "README: inspect structured diagnostics" {
let result = render_svg("<svg><broken></svg>", 8, 8, RenderOptions::default())
assert_eq(result.image.width(), 8)
assert_true(result.diagnostics.length() > 0)
assert_eq(result.diagnostics[0].kind, ParseFailed)
}///|
test "README: resolve a raster image" {
let options = RenderOptions::with_image_resolver(fn(href) {
if href == "asset.png" {
Some(Image::filled(2, 2, Color::rgba(255, 0, 0, 128)))
} else {
None
}
})
let result = render_svg(
"<svg width=\"2\" height=\"2\"><image href=\"asset.png\" width=\"2\" height=\"2\"/></svg>",
2, 2, options,
)
assert_eq(result.image.width(), 2)
assert_eq(result.diagnostics.length(), 0)
}///|
test "README: render with host text resources and static state" {
let options = RenderOptions::{
..RenderOptions::default(),
environment: {
..RenderEnvironment::default(),
base_uri: "mem:/document.svg",
color_scheme: Dark,
sample_time_seconds: 0.5,
element_state_resolver: Some(fn(id) {
if id == "target" {
{ ..ElementState::none(), hover: true }
} else {
ElementState::none()
}
}),
},
text_resource_resolver: Some(fn(uri, kind) {
match (uri, kind) {
("mem:/theme.css", Stylesheet) => Some("#target:hover { fill: red; }")
_ => None
}
}),
}
let source = "<?xml-stylesheet href=\"theme.css\"?><svg width=\"2\" height=\"2\"><rect id=\"target\" width=\"2\" height=\"2\"/></svg>"
let result = render_svg(source, 2, 2, options)
assert_eq(result.diagnostics.length(), 0)
}pub(all) struct BoundingBox {
min_x : Double
min_y : Double
max_x : Double
max_y : Double
}pub(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 FilterGraph {
id : String
primitives : Array[FilterGraphPrimitive]
units : MaskUnits
primitive_units : MaskUnits
x : Double
y : Double
width : Double
height : Double
x_is_percent : Bool
y_is_percent : Bool
width_is_percent : Bool
height_is_percent : Bool
}pub(all) enum FilterGraphPrimitive {
GraphColorMatrix(input~ : String, result~ : String, matrix~ : FixedArray[Double])
GraphGaussianBlur(input~ : String, result~ : String, radius_x~ : Double, radius_y~ : Double)
GraphOffset(input~ : String, result~ : String, dx~ : Double, dy~ : Double)
GraphBlend(input~ : String, input2~ : String, result~ : String, mode~ : BlendMode)
GraphComposite(input~ : String, input2~ : String, result~ : String, operator~ : FilterCompositeOperator, k1~ : Double, k2~ : Double, k3~ : Double, k4~ : Double)
GraphFlood(result~ : String, color~ : Color)
GraphMerge(result~ : String, inputs~ : Array[String])
GraphComponentTransfer(input~ : String, result~ : String, red~ : ComponentTransferFunction, green~ : ComponentTransferFunction, blue~ : ComponentTransferFunction, alpha~ : ComponentTransferFunction)
GraphMorphology(input~ : String, result~ : String, radius_x~ : Double, radius_y~ : Double, operator~ : MorphologyOperator)
GraphConvolveMatrix(input~ : String, result~ : String, order_x~ : Int, order_y~ : Int, kernel~ : Array[Double], divisor~ : Double, bias~ : Double, target_x~ : Int, target_y~ : Int, edge_mode~ : FilterEdgeMode, preserve_alpha~ : Bool)
GraphDisplacementMap(input~ : String, input2~ : String, result~ : String, scale~ : Double, x_channel~ : FilterChannel, y_channel~ : FilterChannel)
GraphTurbulence(result~ : String, base_x~ : Double, base_y~ : Double, octaves~ : Int, seed~ : Double, stitch~ : Bool, fractal_noise~ : Bool)
GraphTile(input~ : String, result~ : String)
GraphImage(result~ : String, href~ : String, x~ : Double, y~ : Double, width~ : Double, height~ : Double)
GraphDiffuseLighting(input~ : String, result~ : String, surface_scale~ : Double, diffuse_constant~ : Double, color~ : Color, light~ : FilterLight)
GraphSpecularLighting(input~ : String, result~ : String, surface_scale~ : Double, specular_constant~ : Double, specular_exponent~ : Double, color~ : Color, light~ : FilterLight)
} derive(Debug)pub(all) enum FilterLight {
DistantLight(azimuth~ : Double, elevation~ : Double)
PointLight(x~ : Double, y~ : Double, z~ : Double)
SpotLight(x~ : Double, y~ : Double, z~ : Double, points_at_x~ : Double, points_at_y~ : Double, points_at_z~ : Double, exponent~ : Double, limiting_cone_angle~ : Double?)
} derive(Debug)pub struct Image {
// private fields
}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 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) 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 Pattern {
id : String
x : Double
y : Double
width : Double
height : Double
content : Array[SVGNode]
pattern_units : PatternUnits
pattern_content_units : PatternUnits
transform : Transform
view_box : ViewBox?
preserve_aspect_ratio : PreserveAspectRatio
}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::new(cx : Double, cy : Double, r : Double, stops : Array[GradientStop]) -> RadialGradientpub(all) struct RenderDiagnostic {
kind : RenderDiagnosticKind
stage : RenderStage
resource : String
node_id : String
}pub(all) struct RenderEnvironment {
base_uri : String
device_pixel_ratio : Double
color_scheme : PreferredColorScheme
sample_time_seconds : Double
element_state_resolver : (String) -> ElementState?
}pub(all) struct RenderOptions {
image_resolver : (String) -> Image??
text_resource_resolver : (String, TextResourceKind) -> String??
environment : RenderEnvironment
max_external_depth : Int
max_external_resources : Int
max_external_bytes : Int
}fn RenderOptions::with_text_resource_resolver(text_resource_resolver : (String, TextResourceKind) -> String?) -> RenderOptionspub struct SVGDocument {
// private fields
}pub(all) struct SVGNode {
id : String
shape : Shape
transform : Transform
view_box : ViewBox?
viewport_width : Double?
viewport_height : Double?
preserve_aspect_ratio : PreserveAspectRatio
image_sampling : ImageSampling
fill : Paint
color : Color?
paint_order : PaintOrder
fill_rule : FillRule
clip_rule : FillRule
fill_opacity : Double
stroke : StrokeStyle
stroke_opacity : Double
opacity : Double
blend_mode : BlendMode
isolation : Isolation
marker_start : String?
marker_mid : String?
marker_end : String?
clip_overflow : Bool
children : Array[SVGNode]
// private fields
}pub(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 Symbol {
id : String
content : SVGNode
view_box : ViewBox?
width : Double?
height : Double?
preserve_aspect_ratio : PreserveAspectRatio
display_none : Bool
}pub(all) struct Transform {
a : Double
b : Double
c : Double
d : Double
e : Double
f : Double
}pub(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) -> Transformfn render_path_commands_to_image(commands : Array[PathCommand], width : Int, height : Int, fill_color : Color, transform? : Array[Double]) -> Imagefn render_svg_document(document : SVGDocument, width : Int, height : Int, options : RenderOptions) -> RenderResultStandalone SVG scene graph and renderer
Dependencies