Skip to content

feat: support SVG <pattern> paint server #589

@softmarshmallow

Description

@softmarshmallow

Summary

Add support for SVG <pattern> elements as a paint type in the rendering engine, SVG import, and serialization.

Currently usvg::Paint::Pattern is parsed correctly by our vendored usvg fork, but the SVG-to-IR conversion discards it silently (falls back to SVGPaint::TRANSPARENT, tagged [MODEL_MISMATCH]). Any SVG with pattern fills renders with missing content.

Motivation

  • <pattern> is a core SVG paint server — dropping it causes visual fidelity loss on import.
  • Many real-world SVGs use patterns for textures, hatching, dot grids, and repeating motifs.
  • Figma exposes a PATTERN paint type; supporting it enables better round-trip fidelity.

Design

Pattern should be modeled as a paint type, not a scene graph node. This is consistent with:

  • The SVG spec (paint server, same category as gradients)
  • Chromium (hidden resource container that produces a tiling shader — never a visual node or compositor layer)
  • Figma (PATTERN paint type in the fills array)
  • Our existing ImagePaintFit::Tile infrastructure

See docs/wg/feat-svg/pattern.md for full design analysis and docs/wg/research/chromium/svg-pattern.md for Chromium's implementation details.

Scope

Core engine (crates/grida-canvas)

  • Add SVGPatternPaint struct and SVGPaint::Pattern variant
  • Convert usvg::Paint::Pattern during from_usvg instead of discarding
  • Implement pattern rendering — record pattern subtree into a Skia Picture, use Picture::to_shader(TileMode::Repeat, ...) to create a tiling shader
  • Handle patternUnits, patternContentUnits, patternTransform, viewBox
  • Serialization: .grida roundtrip for the new paint type

SVG export

  • Emit <pattern> definitions and url(#id) references when exporting

Runtime Paint enum (optional, for non-SVG usage)

  • Consider adding Paint::Pattern(...) variant or reusing Paint::Image with ImagePaintFit::Tile after pre-rasterization

References

  • SVG spec: https://www.w3.org/TR/SVG11/pservers.html#Patterns
  • Chromium: third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.cc
  • Skia: SkPicture::makeShader() / rust-skia Picture::to_shader()
  • Design doc: docs/wg/feat-svg/pattern.md
  • Research doc: docs/wg/research/chromium/svg-pattern.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions