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)
SVG export
Runtime Paint enum (optional, for non-SVG usage)
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
Summary
Add support for SVG
<pattern>elements as a paint type in the rendering engine, SVG import, and serialization.Currently
usvg::Paint::Patternis parsed correctly by our vendored usvg fork, but the SVG-to-IR conversion discards it silently (falls back toSVGPaint::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.PATTERNpaint 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:
PATTERNpaint type in the fills array)ImagePaintFit::TileinfrastructureSee
docs/wg/feat-svg/pattern.mdfor full design analysis anddocs/wg/research/chromium/svg-pattern.mdfor Chromium's implementation details.Scope
Core engine (
crates/grida-canvas)SVGPatternPaintstruct andSVGPaint::Patternvariantusvg::Paint::Patternduringfrom_usvginstead of discardingPicture, usePicture::to_shader(TileMode::Repeat, ...)to create a tiling shaderpatternUnits,patternContentUnits,patternTransform,viewBox.gridaroundtrip for the new paint typeSVG export
<pattern>definitions andurl(#id)references when exportingRuntime
Paintenum (optional, for non-SVG usage)Paint::Pattern(...)variant or reusingPaint::ImagewithImagePaintFit::Tileafter pre-rasterizationReferences
third_party/blink/renderer/core/layout/svg/layout_svg_resource_pattern.ccSkPicture::makeShader()/ rust-skiaPicture::to_shader()docs/wg/feat-svg/pattern.mddocs/wg/research/chromium/svg-pattern.md