svg

    Standalone SVG scene graph and renderer

    svg
    graphics
    Download zip
    Author
    Version
    0.5.3
    License
    Apache-2.0
    Last updated
    14 days ago
    Downloads
    1K

    Dependencies

    #Milky2018/svg

    A standalone SVG parser and deterministic CPU renderer for MoonBit. It renders SVG markup or an SVGDocument into an owned RGBA Image.

    #Install

    moon add Milky2018/svg

    #Migrating from 0.3.x

    Version 0.4.0 removes the combinatorial document, node, scene, and resolver rendering functions. Rendering now goes through an owned Image facade, and image resolution is configured with RenderOptions.

    0.3.x API0.4.0 replacementNotes
    parse_svg(source)parse_svg_document(source).map(fn(document) { document.root() })Use the document result when resources are needed.
    parse_svg_document(source)UnchangedReturns SVGDocument?.
    render_svg(source, width, height, options)UnchangedReturns RenderResult with an owned image and diagnostics.
    render_svg_to_image(source, width, height)UnchangedRemains 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()).imageUse the structured result when diagnostics matter.
    render_svg_document_to_image_with_resolver(...)render_svg_document(document, width, height, RenderOptions::with_image_resolver(resolver)).imageResolver configuration is no longer a separate function family.
    render_svg_node_to_image*render_svg_document(SVGDocument::new(node), width, height, options).imageRegister referenced resources on the document before rendering.
    render_svg_scene_to_image* and SceneNo direct replacementMigrate authored content to SVGDocument and SVGNode.
    PixelSetter, RenderContext, context-driven .render, and public raster_* functionsNo direct replacementThe renderer owns its target image; use the rendering facade.
    render_path_commands_to_image(...)UnchangedRemains the expert direct-path entry point.

    #Parse and Render

    ///|
    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(_))
    }

    Use the document API when the parsed resource tables or root node are needed:

    ///|
    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")
    }
    }

    #Structured Results

    render_svg always returns an image and typed diagnostics. A malformed document produces a transparent image plus a ParseFailed diagnostic instead of requiring a separate error channel.

    ///|
    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)
    }

    #Host-Provided Raster Images

    The renderer passes each <image href> string to the resolver. The host owns file or network access, decoding, caching, and policy; return None when a resource cannot be resolved.

    ///|
    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)
    }

    Resolved images participate in preserveAspectRatio, affine transforms, clipping, opacity, and compositing. External SVG resource documents are not resolved by this callback.

    #Static Render Environment and Text Resources

    RenderEnvironment makes every non-document input to a snapshot explicit: the document base URI, device pixel ratio, preferred color scheme, animation sample time, and per-element interaction state. text_resource_resolver supplies CSS or SVG text after URI resolution. The library never reads files or performs network requests.

    ///|
    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)
    }

    External CSS supports xml-stylesheet processing instructions and recursive @import. External SVG fragments used by <use>, paint servers, clip paths, masks, filters, patterns, and markers share the same bounded, cached resolver. Relative references use the containing document or stylesheet URI. Missing, cyclic, oversized, over-deep, or over-count resources fail closed and produce typed diagnostics. Defaults allow 16 nested resources, 64 distinct resources, and 16 MiB of resolved text; callers may lower these limits in RenderOptions.

    The explicit sample time evaluates CSS keyframes without a clock. The initial interpolation set covers geometry lengths, affine transforms, colors, opacity, and paint opacity; other properties are discrete. Paused animations have a deterministic hold time of zero because a static document has no prior running timeline. SMIL, scripting, DOM mutation, event dispatch, and live restyling are outside this API.

    #Main API

    • Parsing: parse_svg_document, parse_path, parse_transform
    • Rendering: render_svg, render_svg_document, render_svg_to_image
    • Results: RenderResult, RenderDiagnostic, RenderOptions, RenderEnvironment
    • Data: SVGDocument, SVGNode, Shape, Image, Color
    • Direct paths: render_path_commands_to_image

    The renderer owns its pixel target. Former low-level context and raster functions are implementation details and are not public APIs.

    #Static CSS Support

    Presentation attributes, embedded <style> rules, and inline declarations use the shared Milky2018/css cascade. Supported behavior includes selector specificity and source order, !important, inheritance, CSS-wide keywords, inherited custom properties and nested var() fallbacks, currentColor, and CSS Color 3 named, RGB/RGBA, HSL/HSLA, and hex colors.

    The same computed path covers SVG paint and stroke properties, markers, paint order, fill and clip rules, geometry properties, transforms, gradient stops, and basic text font-size. Length expressions retain their unit and percentage semantics until an SVG axis, nested viewport, font context, and outer CSS viewport are available.

    This is a static-document model, not a browser DOM. Host-provided external stylesheets, forced interaction pseudo-classes, media inputs, and sampled CSS keyframes are supported as immutable snapshot inputs. Scripting, dynamic restyling, cascade layers, SMIL, event dispatch, and a browser animation clock are intentionally excluded.

    #Rendering Contract

    The implementation aims for internally consistent SVG semantics and stable software output. It does not guarantee pixel-for-pixel parity with Chromium, Skia, or platform text engines. Nested SVG text layout remains outside the supported core.

    #License and Attribution

    Milky2018/svg is distributed under Apache-2.0 and depends on the separately published Milky2018/css module. See NOTICE for the CSS dependency's source origin and attribution.

    Align

    pub(all) enum Align {
    None
    XMinYMin
    XMidYMin
    XMaxYMin
    XMinYMid
    XMidYMid
    XMaxYMid
    XMinYMax
    XMidYMax
    XMaxYMax
    } derive(Eq,
    Debug
    )

    preserveAspectRatio alignment values
    impl Show for Align

    Align::equal

    fn Align::equal(Align, Align) -> Bool

    Align::not_equal

    fn Align::not_equal(x : Align, y : Align) -> Bool

    Align::output

    fn Align::output(self : Align, logger : &Logger) -> Unit

    Align::to_repr

    Align::to_string

    fn Align::to_string(self : Align) -> String

    BlendMode

    pub(all) enum BlendMode {
    Normal
    Multiply
    Screen
    Overlay
    Darken
    Lighten
    ColorDodge
    ColorBurn
    HardLight
    SoftLight
    Difference
    Exclusion
    Hue
    Saturation
    ColorMode
    Luminosity
    } derive(Eq,
    Debug
    )

    CSS mix-blend-mode values

    BlendMode::equal

    fn BlendMode::equal(BlendMode, BlendMode) -> Bool

    BlendMode::not_equal

    fn BlendMode::not_equal(x : BlendMode, y : BlendMode) -> Bool

    BoundingBox

    pub(all) struct BoundingBox {
    min_x : Double
    min_y : Double
    max_x : Double
    max_y : Double
    }

    Bounding box for a shape

    BoundingBox::contains_point

    fn BoundingBox::contains_point(self : BoundingBox, x : Double, y : Double) -> Bool

    Check if this bounding box contains a point

    BoundingBox::empty

    fn BoundingBox::empty() -> BoundingBox

    BoundingBox::expand_by_point

    fn BoundingBox::expand_by_point(self : BoundingBox, x : Double, y : Double) -> BoundingBox

    BoundingBox::from_rect

    fn BoundingBox::from_rect(x : Double, y : Double, w : Double, h : Double) -> BoundingBox

    BoundingBox::height

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

    BoundingBox::intersects

    fn BoundingBox::intersects(self : BoundingBox, other : BoundingBox) -> Bool

    Check if two bounding boxes intersect

    BoundingBox::is_empty

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

    BoundingBox::union

    fn BoundingBox::union(self : BoundingBox, other : BoundingBox) -> BoundingBox

    BoundingBox::width

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

    ClipPath

    pub(all) struct ClipPath {
    id : String
    shape : Shape
    content : Array[SVGNode]
    transform : Transform
    clip_rule : FillRule
    units : ClipPathUnits
    }

    Clip path definition

    ClipPath::new

    fn ClipPath::new(id : String, shape : Shape) -> ClipPath

    ClipPath::with_transform

    fn ClipPath::with_transform(id : String, shape : Shape, transform : Transform) -> ClipPath

    ClipPathUnits

    pub(all) enum ClipPathUnits {
    UserSpaceOnUse
    ObjectBoundingBox
    } derive(Eq,
    Debug
    )

    Clip path units for coordinate system

    ClipPathUnits::equal

    ClipPathUnits::not_equal

    fn ClipPathUnits::not_equal(x : ClipPathUnits, y : ClipPathUnits) -> Bool

    Color

    pub(all) struct Color {
    r : Int
    g : Int
    b : Int
    a : Int
    } derive(
    Debug
    )

    RGB Color (0-255 range)

    Color::black

    fn Color::black() -> Color

    Color::is_transparent

    fn Color::is_transparent(self : Color) -> Bool

    Color::rgb

    fn Color::rgb(r : Int, g : Int, b : Int) -> Color

    Color::rgba

    fn Color::rgba(r : Int, g : Int, b : Int, a : Int) -> Color

    Color::to_repr

    Color::transparent

    fn Color::transparent() -> Color

    Color::white

    fn Color::white() -> Color

    ComponentTransferFunction

    pub(all) enum ComponentTransferFunction {
    TransferIdentity
    TransferTable(Array[Double])
    TransferDiscrete(Array[Double])
    TransferLinear(slope~ : Double, intercept~ : Double)
    TransferGamma(amplitude~ : Double, exponent~ : Double, offset~ : Double)
    } derive(
    Debug
    )

    ElementState

    pub(all) struct ElementState {
    hover : Bool
    focus : Bool
    active : Bool
    focus_visible : Bool
    focus_within : Bool
    } derive(Eq,
    Debug
    )

    ElementState::equal

    ElementState::none

    ElementState::not_equal

    fn ElementState::not_equal(x : ElementState, y : ElementState) -> Bool

    FillRule

    pub(all) enum FillRule {
    NonZero
    EvenOdd
    } derive(Eq,
    Debug
    )

    Fill rule for paths and polygons
    impl Show for FillRule

    FillRule::equal

    fn FillRule::equal(FillRule, FillRule) -> Bool

    FillRule::not_equal

    fn FillRule::not_equal(x : FillRule, y : FillRule) -> Bool

    FillRule::output

    fn FillRule::output(self : FillRule, logger : &Logger) -> Unit

    FillRule::to_repr

    FillRule::to_string

    fn FillRule::to_string(self : FillRule) -> String

    Filter

    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])
    }

    Filter types

    FilterChannel

    pub(all) enum FilterChannel {
    ChannelR
    ChannelG
    ChannelB
    ChannelA
    } derive(Eq,
    Debug
    )

    FilterChannel::equal

    FilterChannel::not_equal

    fn FilterChannel::not_equal(x : FilterChannel, y : FilterChannel) -> Bool

    FilterCompositeOperator

    pub(all) enum FilterCompositeOperator {
    CompositeOver
    CompositeIn
    CompositeOut
    CompositeAtop
    CompositeXor
    CompositeArithmetic
    } derive(Eq,
    Debug
    )

    FilterCompositeOperator::equal

    FilterCompositeOperator::not_equal

    FilterEdgeMode

    pub(all) enum FilterEdgeMode {
    EdgeDuplicate
    EdgeWrap
    EdgeNone
    } derive(Eq,
    Debug
    )

    FilterEdgeMode::equal

    FilterEdgeMode::not_equal

    fn FilterEdgeMode::not_equal(x : FilterEdgeMode, y : FilterEdgeMode) -> Bool

    FilterGraph

    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
    }

    FilterGraphPrimitive

    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
    )

    FilterLight

    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
    )

    Gradient

    pub(all) enum Gradient {
    Linear(LinearGradient)
    Radial(RadialGradient)
    }

    Gradient definitions

    GradientStop

    pub(all) struct GradientStop {
    offset : Double
    color : Color
    }

    Gradient stop (position 0.0-1.0 and color)

    GradientUnits

    pub(all) enum GradientUnits {
    UserSpaceOnUse
    ObjectBoundingBox
    } derive(Eq,
    Debug
    )

    Gradient units coordinate space

    GradientUnits::equal

    GradientUnits::not_equal

    fn GradientUnits::not_equal(x : GradientUnits, y : GradientUnits) -> Bool

    Image

    pub struct Image {
    // private fields
    }

    Image data (RGBA pixels)

    Image::filled

    fn Image::filled(width : Int, height : Int, color : Color) -> Image

    Create an image filled with a color

    Image::from_pixels

    fn Image::from_pixels(width : Int, height : Int, source : Array[Color]) -> Image?

    Create an image from row-major RGBA pixels when dimensions match exactly.

    Image::get_pixel

    fn Image::get_pixel(self : Image, x : Int, y : Int) -> Color

    Get pixel at coordinates

    Image::height

    fn Image::height(self : Image) -> Int

    Image::new

    fn Image::new(width : Int, height : Int) -> Image

    Create a new image with specified dimensions

    Image::set_pixel

    fn Image::set_pixel(self : Image, x : Int, y : Int, color : Color) -> Unit

    Set pixel at coordinates

    Image::width

    fn Image::width(self : Image) -> Int

    ImageSampling

    pub(all) enum ImageSampling {
    Nearest
    Bilinear
    Bicubic
    } derive(Eq,
    Debug
    )

    ImageSampling::equal

    ImageSampling::not_equal

    fn ImageSampling::not_equal(x : ImageSampling, y : ImageSampling) -> Bool

    Isolation

    pub(all) enum Isolation {
    Auto
    Isolate
    } derive(Eq,
    Debug
    )

    CSS isolation values

    Isolation::equal

    fn Isolation::equal(Isolation, Isolation) -> Bool

    Isolation::not_equal

    fn Isolation::not_equal(x : Isolation, y : Isolation) -> Bool

    LineCap

    pub(all) enum LineCap {
    Butt
    Round
    Square
    } derive(Eq,
    Debug
    )

    impl Show for LineCap

    LineCap::equal

    fn LineCap::equal(LineCap, LineCap) -> Bool

    LineCap::not_equal

    fn LineCap::not_equal(x : LineCap, y : LineCap) -> Bool

    LineCap::output

    fn LineCap::output(self : LineCap, logger : &Logger) -> Unit

    LineCap::to_repr

    LineCap::to_string

    fn LineCap::to_string(self : LineCap) -> String

    LineJoin

    pub(all) enum LineJoin {
    Miter
    Round
    Bevel
    } derive(Eq,
    Debug
    )

    impl Show for LineJoin

    LineJoin::equal

    fn LineJoin::equal(LineJoin, LineJoin) -> Bool

    LineJoin::not_equal

    fn LineJoin::not_equal(x : LineJoin, y : LineJoin) -> Bool

    LineJoin::output

    fn LineJoin::output(self : LineJoin, logger : &Logger) -> Unit

    LineJoin::to_repr

    LineJoin::to_string

    fn LineJoin::to_string(self : LineJoin) -> String

    LinearGradient

    pub(all) struct LinearGradient {
    x1 : Double
    y1 : Double
    x2 : Double
    y2 : Double
    stops : Array[GradientStop]
    spread_method : SpreadMethod
    units : GradientUnits
    transform : Transform
    }

    Linear gradient definition

    LinearGradient::new

    fn LinearGradient::new(x1 : Double, y1 : Double, x2 : Double, y2 : Double, stops : Array[GradientStop]) -> LinearGradient

    Marker

    pub(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
    }

    Marker definition (for line endpoints)

    Marker::new

    fn Marker::new(id : String, content : SVGNode) -> Marker

    MarkerOrient

    pub(all) enum MarkerOrient {
    Auto
    AutoStartReverse
    Angle(Double)
    }

    MarkerUnits

    pub(all) enum MarkerUnits {
    StrokeWidth
    UserSpaceOnUse_
    }

    Mask

    pub(all) struct Mask {
    id : String
    content : Array[SVGNode]
    x : Double
    y : Double
    width : Double
    height : Double
    x_is_percent : Bool
    y_is_percent : Bool
    width_is_percent : Bool
    height_is_percent : Bool
    mask_units : MaskUnits
    mask_content_units : MaskUnits
    mask_type : MaskType
    }

    Mask definition for transparency masking

    Mask::new

    fn Mask::new(id : String, content : Array[SVGNode]) -> Mask

    Mask::with_bounds

    fn Mask::with_bounds(id : String, content : Array[SVGNode], x : Double, y : Double, width : Double, height : Double) -> Mask

    MaskType

    pub(all) enum MaskType {
    Luminance
    Alpha
    } derive(Eq,
    Debug
    )

    Mask type - how mask values are interpreted
    impl Show for MaskType

    MaskType::equal

    fn MaskType::equal(MaskType, MaskType) -> Bool

    MaskType::not_equal

    fn MaskType::not_equal(x : MaskType, y : MaskType) -> Bool

    MaskType::output

    fn MaskType::output(self : MaskType, logger : &Logger) -> Unit

    MaskType::to_repr

    MaskType::to_string

    fn MaskType::to_string(self : MaskType) -> String

    MaskUnits

    pub(all) enum MaskUnits {
    UserSpaceOnUse
    ObjectBoundingBox
    } derive(Eq,
    Debug
    )

    Mask content units

    MaskUnits::equal

    fn MaskUnits::equal(MaskUnits, MaskUnits) -> Bool

    MaskUnits::not_equal

    fn MaskUnits::not_equal(x : MaskUnits, y : MaskUnits) -> Bool

    MeetOrSlice

    pub(all) enum MeetOrSlice {
    Meet
    Slice
    } derive(Eq,
    Debug
    )

    preserveAspectRatio meet/slice
    impl Show for MeetOrSlice

    MeetOrSlice::equal

    fn MeetOrSlice::equal(MeetOrSlice, MeetOrSlice) -> Bool

    MeetOrSlice::not_equal

    fn MeetOrSlice::not_equal(x : MeetOrSlice, y : MeetOrSlice) -> Bool

    MeetOrSlice::output

    fn MeetOrSlice::output(self : MeetOrSlice, logger : &Logger) -> Unit

    MeetOrSlice::to_string

    fn MeetOrSlice::to_string(self : MeetOrSlice) -> String

    MorphologyOperator

    pub(all) enum MorphologyOperator {
    MorphologyErode
    MorphologyDilate
    } derive(Eq,
    Debug
    )

    MorphologyOperator::equal

    MorphologyOperator::not_equal

    Paint

    pub(all) enum Paint {
    None
    SolidColor(Color)
    LinearGrad(LinearGradient)
    RadialGrad(RadialGradient)
    CurrentColor
    PaintServerRef(String, PaintFallback)
    }

    Paint style (fill or stroke)

    PaintFallback

    pub(all) enum PaintFallback {
    NoPaint
    SolidColor(Color)
    CurrentColor
    }

    Paint style (fill or stroke)

    PaintOrder

    pub(all) struct PaintOrder {
    order : Array[PaintOrderItem]
    } derive(Eq,
    Debug
    )

    SVG paint-order specification.

    PaintOrder::default

    fn PaintOrder::default() -> PaintOrder

    PaintOrder::equal

    fn PaintOrder::equal(PaintOrder, PaintOrder) -> Bool

    PaintOrder::not_equal

    fn PaintOrder::not_equal(x : PaintOrder, y : PaintOrder) -> Bool

    PaintOrderItem

    pub(all) enum PaintOrderItem {
    Fill
    Stroke
    Markers
    } derive(Eq,
    Debug
    )

    SVG paint-order components.

    PaintOrderItem::equal

    PaintOrderItem::not_equal

    fn PaintOrderItem::not_equal(x : PaintOrderItem, y : PaintOrderItem) -> Bool

    PaintOrderItem::output

    fn PaintOrderItem::output(self : PaintOrderItem, logger : &Logger) -> Unit

    PaintOrderItem::to_string

    fn PaintOrderItem::to_string(self : PaintOrderItem) -> String

    PathCommand

    pub(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
    )

    SVG path commands (full SVG 1.1 spec)

    Pattern

    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
    }

    Pattern definition for fills

    Pattern::new

    fn Pattern::new(id : String, width : Double, height : Double, content : Array[SVGNode]) -> Pattern

    PatternUnits

    pub(all) enum PatternUnits {
    UserSpaceOnUse
    ObjectBoundingBox
    }

    PreferredColorScheme

    pub(all) enum PreferredColorScheme {
    Light
    Dark
    } derive(Eq,
    Debug
    )

    PreferredColorScheme::equal

    PreferredColorScheme::not_equal

    PreserveAspectRatio

    pub(all) struct PreserveAspectRatio {
    align : Align
    meet_or_slice : MeetOrSlice
    }

    Complete preserveAspectRatio setting

    PreserveAspectRatio::default

    RadialGradient

    pub(all) struct RadialGradient {
    cx : Double
    cy : Double
    fx : Double
    fy : Double
    r : Double
    stops : Array[GradientStop]
    spread_method : SpreadMethod
    units : GradientUnits
    transform : Transform
    }

    Radial gradient definition

    RadialGradient::new

    fn RadialGradient::new(cx : Double, cy : Double, r : Double, stops : Array[GradientStop]) -> RadialGradient

    RenderDiagnostic

    pub(all) struct RenderDiagnostic {
    kind : RenderDiagnosticKind
    stage : RenderStage
    resource : String
    node_id : String
    }

    RenderDiagnosticKind

    pub(all) enum RenderDiagnosticKind {
    ParseFailed
    ResourceUnresolved
    ResourceCycle
    ResourceLimitExceeded
    } derive(Eq,
    Debug
    )

    RenderDiagnosticKind::equal

    RenderDiagnosticKind::not_equal

    RenderEnvironment

    pub(all) struct RenderEnvironment {
    base_uri : String
    device_pixel_ratio : Double
    color_scheme : PreferredColorScheme
    sample_time_seconds : Double
    element_state_resolver : (String) -> ElementState?
    }

    Static inputs used while parsing and computing an SVG snapshot.

    RenderEnvironment::default

    RenderOptions

    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
    }

    RenderOptions::default

    fn RenderOptions::default() -> RenderOptions

    RenderOptions::with_image_resolver

    fn RenderOptions::with_image_resolver(image_resolver : (String) -> Image?) -> RenderOptions

    Return these options with a host callback for decoded raster images.

    RenderOptions::with_text_resource_resolver

    fn RenderOptions::with_text_resource_resolver(text_resource_resolver : (String, TextResourceKind) -> String?) -> RenderOptions

    Return these options with a host callback for CSS and SVG text resources.

    RenderResult

    pub(all) struct RenderResult {
    image : Image
    diagnostics : Array[RenderDiagnostic]
    }

    RenderStage

    pub(all) enum RenderStage {
    Document
    Stylesheet
    Paint
    Image
    Effects
    } derive(Eq,
    Debug
    )

    RenderStage::equal

    fn RenderStage::equal(RenderStage, RenderStage) -> Bool

    RenderStage::not_equal

    fn RenderStage::not_equal(x : RenderStage, y : RenderStage) -> Bool

    SVGDocument

    pub struct SVGDocument {
    // private fields
    }

    Parsed SVG document with reusable resources

    SVGDocument::add_clip_path

    fn SVGDocument::add_clip_path(self : SVGDocument, clip : ClipPath) -> Unit

    SVGDocument::add_definition

    fn SVGDocument::add_definition(self : SVGDocument, id : String, node : SVGNode) -> Unit

    Register an ordinary SVG node for fragment references such as <use>.

    SVGDocument::add_filter_graph

    fn SVGDocument::add_filter_graph(self : SVGDocument, filter : FilterGraph) -> Unit

    SVGDocument::add_gradient

    fn SVGDocument::add_gradient(self : SVGDocument, id : String, gradient : Gradient) -> Unit

    SVGDocument::add_marker

    fn SVGDocument::add_marker(self : SVGDocument, marker : Marker) -> Unit

    SVGDocument::add_mask

    fn SVGDocument::add_mask(self : SVGDocument, mask : Mask) -> Unit

    SVGDocument::add_pattern

    fn SVGDocument::add_pattern(self : SVGDocument, pattern : Pattern) -> Unit

    SVGDocument::add_symbol

    fn SVGDocument::add_symbol(self : SVGDocument, symbol : Symbol) -> Unit

    SVGDocument::instantiate_use

    fn SVGDocument::instantiate_use(self : SVGDocument, element : UseElement) -> SVGNode?

    Instantiate a reusable element registered on this document.

    SVGDocument::new

    fn SVGDocument::new(root : SVGNode) -> SVGDocument

    SVGDocument::root

    fn SVGDocument::root(self : SVGDocument) -> SVGNode

    Return the authored root node.

    SVGNode

    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
    }

    SVG node (element in the scene graph)

    SVGNode::add_filter

    fn SVGNode::add_filter(self : SVGNode, filter : Filter) -> Unit

    Add a filter to the node

    SVGNode::clear_clip_path

    fn SVGNode::clear_clip_path(self : SVGNode) -> Unit

    Clear clip path reference

    SVGNode::clear_filter_graph

    fn SVGNode::clear_filter_graph(self : SVGNode) -> Unit

    SVGNode::clear_filters

    fn SVGNode::clear_filters(self : SVGNode) -> Unit

    Clear all filters from the node

    SVGNode::clear_mask

    fn SVGNode::clear_mask(self : SVGNode) -> Unit

    Clear mask reference

    SVGNode::new

    fn SVGNode::new(shape : Shape) -> SVGNode

    SVGNode::set_clip_path

    fn SVGNode::set_clip_path(self : SVGNode, clip_path_id : String) -> Unit

    Set clip path reference by ID

    SVGNode::set_filter_graph

    fn SVGNode::set_filter_graph(self : SVGNode, filter_id : String) -> Unit

    Set an SVG filter graph reference by ID.

    SVGNode::set_mask

    fn SVGNode::set_mask(self : SVGNode, mask_id : String) -> Unit

    Set mask reference by ID

    Shape

    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
    )

    SVG shape primitives

    Shape::to_repr

    SpreadMethod

    pub(all) enum SpreadMethod {
    Pad
    Repeat
    Reflect
    } derive(Eq,
    Debug
    )

    How gradient extends beyond its bounds

    SpreadMethod::equal

    SpreadMethod::not_equal

    fn SpreadMethod::not_equal(x : SpreadMethod, y : SpreadMethod) -> Bool

    StrokeStyle

    pub(all) struct StrokeStyle {
    paint : Paint
    width : Double
    linecap : LineCap
    linejoin : LineJoin
    miterlimit : Double
    dasharray : Array[Double]?
    dashoffset : Double
    non_scaling : Bool
    }

    Stroke properties

    StrokeStyle::default

    fn StrokeStyle::default() -> StrokeStyle

    Symbol

    pub(all) struct Symbol {
    id : String
    content : SVGNode
    view_box : ViewBox?
    width : Double?
    height : Double?
    preserve_aspect_ratio : PreserveAspectRatio
    display_none : Bool
    }

    Symbol definition (reusable graphic)

    Symbol::new

    fn Symbol::new(id : String, content : SVGNode) -> Symbol

    Symbol::with_viewbox

    fn Symbol::with_viewbox(id : String, content : SVGNode, view_box : ViewBox) -> Symbol

    TextResourceKind

    pub(all) enum TextResourceKind {
    Stylesheet
    SvgDocument
    } derive(Eq,
    Debug
    )

    TextResourceKind::equal

    TextResourceKind::not_equal

    fn TextResourceKind::not_equal(x : TextResourceKind, y : TextResourceKind) -> Bool

    Transform

    pub(all) struct Transform {
    a : Double
    b : Double
    c : Double
    d : Double
    e : Double
    f : Double
    }

    2D affine transformation matrix | a c e | | b d f | | 0 0 1 |

    Transform::apply

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

    Apply transform to a point

    Transform::apply_bbox

    fn Transform::apply_bbox(self : Transform, bbox : BoundingBox) -> BoundingBox

    Transform a bounding box (returns axis-aligned bounding box of transformed corners)

    Transform::apply_point

    fn Transform::apply_point(self : Transform, point : (Double, Double)) -> (Double, Double)

    Apply transform to a point (struct version)

    Transform::determinant

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

    Compute the determinant of the transform

    Transform::get_rotation

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

    Get the rotation angle in radians (approximate, assumes uniform scale)

    Transform::get_scale

    fn Transform::get_scale(self : Transform) -> (Double, Double)

    Get the scale factors (approximate, assumes no rotation)

    Transform::get_translate

    fn Transform::get_translate(self : Transform) -> (Double, Double)

    Get the translation component

    Transform::inverse

    fn Transform::inverse(self : Transform) -> Transform

    Compute the inverse transform Returns identity if not invertible

    Transform::is_invertible

    fn Transform::is_invertible(self : Transform) -> Bool

    Check if the transform is invertible

    Transform::matrix

    fn Transform::matrix(a : Double, b : Double, c : Double, d : Double, e : Double, f : Double) -> Transform

    Create a transform from a full matrix specification

    Transform::multiply

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

    Multiply two transforms (self * other) Result: first apply other, then apply self

    Transform::rotate

    fn Transform::rotate(angle : Double) -> Transform

    Create a rotation transform (angle in radians)

    Transform::rotate_around

    fn Transform::rotate_around(angle : Double, cx : Double, cy : Double) -> Transform

    Create a rotation transform around a point (angle in radians)

    Transform::scale

    fn Transform::scale(sx : Double, sy : Double) -> Transform

    Create a scaling transform

    Transform::scale_uniform

    fn Transform::scale_uniform(s : Double) -> Transform

    Create a uniform scaling transform

    Transform::skew_x

    fn Transform::skew_x(angle : Double) -> Transform

    Create a skewX transform (angle in radians)

    Transform::skew_y

    fn Transform::skew_y(angle : Double) -> Transform

    Create a skewY transform (angle in radians)

    Transform::translate

    fn Transform::translate(tx : Double, ty : Double) -> Transform

    Create a translation transform

    UseElement

    pub(all) struct UseElement {
    href : String
    x : Double
    y : Double
    width : Double?
    height : Double?
    transform : Transform
    }

    Use element (instance of a symbol)

    UseElement::get_id

    fn UseElement::get_id(self : UseElement) -> String

    Get the href ID (strips leading #)

    UseElement::new

    fn UseElement::new(href : String, x : Double, y : Double) -> UseElement

    UseElement::with_size

    fn UseElement::with_size(href : String, x : Double, y : Double, width : Double, height : Double) -> UseElement

    ViewBox

    pub(all) struct ViewBox {
    min_x : Double
    min_y : Double
    width : Double
    height : Double
    }

    ViewBox specification for SVG coordinate system mapping

    ViewBox::get_transform

    fn ViewBox::get_transform(self : ViewBox, viewport_width : Double, viewport_height : Double, preserve_aspect_ratio : PreserveAspectRatio) -> Transform

    Calculate the transform matrix to map viewBox coordinates to viewport viewport_width/height: the actual pixel dimensions of the SVG element

    parse_path

    fn parse_path(data : String) -> Array[PathCommand]

    Parse a path data string into an array of path commands

    parse_svg_document

    fn parse_svg_document(svg_str : String) -> SVGDocument?

    Parse SVG markup string into SVGDocument with resources

    parse_transform

    fn parse_transform(value : String) -> Transform

    path_bbox

    fn path_bbox(commands : Array[PathCommand]) -> BoundingBox

    Compute bounding box of path commands

    render_path_commands_to_image

    fn render_path_commands_to_image(commands : Array[PathCommand], width : Int, height : Int, fill_color : Color, transform? : Array[Double]) -> Image

    Render PathCommand array directly to an Image (no SVG string parsing). This is much faster than render_svg_to_image for programmatic paths (e.g., font glyph outlines) because it skips SVG serialization and parsing.

    transform is a 6-element affine transform [a, b, c, d, e, f] or empty for identity.

    render_svg

    fn render_svg(svg_str : String, width : Int, height : Int, options : RenderOptions) -> RenderResult

    Parse and render SVG markup with structured diagnostics.

    render_svg_document

    fn render_svg_document(document : SVGDocument, width : Int, height : Int, options : RenderOptions) -> RenderResult

    Render a parsed SVG document with structured diagnostics.

    render_svg_to_image

    fn render_svg_to_image(svg_str : String, width : Int, height : Int) -> Image?

    Parse and render an SVG markup string into an Image.