Skip to content

Add Android VectorDrawable import support#468

Merged
wieslawsoltes merged 3 commits into
masterfrom
feature/vector-drawable-import
Mar 8, 2026
Merged

Add Android VectorDrawable import support#468
wieslawsoltes merged 3 commits into
masterfrom
feature/vector-drawable-import

Conversation

@wieslawsoltes
Copy link
Copy Markdown
Owner

PR Summary: Add Android VectorDrawable import support

Overview

This change implements static Android VectorDrawable import support for Svg.Skia and Svg.Model, based on issue #467.

The implementation converts Android VectorDrawable XML into a real SvgDocument, then reuses the existing Svg.Skia model and rendering pipeline for raster, PDF, XPS, and SVG output paths. In addition to the importer itself, this PR adds:

  • new public APIs for loading VectorDrawable content from file paths, streams, readers, and raw XML strings
  • path-based .xml auto-detection for Android VectorDrawable documents
  • converter sample support for VectorDrawable input and direct SVG output
  • model- and render-level tests
  • a test-only validator generated from pinned Android attrs.xml so Android contract coverage is explicit and reviewable

Main Changes

1. VectorDrawable importer

Added an internal converter in Svg.Model that:

  • validates Android vector roots using the Android XML namespace
  • converts root width, height, viewportWidth, viewportHeight, and alpha
  • converts group elements into SvgGroup instances with a single computed matrix transform
  • converts path elements into SvgPath with mapped fill, stroke, alpha, fill rule, line cap, line join, and miter limit
  • converts clip-path elements into shared SVG defs and applies them to the correct group scope
  • preserves android:name values as SVG IDs where possible
  • fails fast on unsupported Android-only features instead of degrading silently

Unsupported features currently rejected include:

  • animated-vector
  • aapt:attr
  • tint
  • tintMode
  • autoMirrored="true"
  • resource and theme references such as @... and ?...
  • trimPathStart
  • trimPathEnd
  • trimPathOffset

The importer also now enforces Android-style positive root metrics:

  • width > 0
  • height > 0
  • viewportWidth > 0
  • viewportHeight > 0

2. Public API additions

Added SvgService entry points:

  • OpenVectorDrawable(string path, SvgParameters? parameters = null)
  • OpenVectorDrawable(Stream stream, SvgParameters? parameters = null)
  • OpenVectorDrawable(XmlReader reader)
  • FromVectorDrawable(string xml)

Added SKSvg entry points:

  • CreateFromVectorDrawable(string path, SvgParameters? parameters = null)
  • CreateFromVectorDrawable(Stream stream, SvgParameters? parameters = null)
  • CreateFromVectorDrawable(XmlReader reader)
  • LoadVectorDrawable(string path, SvgParameters? parameters = null)
  • LoadVectorDrawable(Stream stream, SvgParameters? parameters = null)
  • LoadVectorDrawable(XmlReader reader)
  • FromVectorDrawable(string xml)

SKSvg.Load(path) and SvgService.Open(path, ...) now auto-detect .xml files whose root is an Android VectorDrawable and route them through the new importer.

3. Converter sample updates

The converter sample now:

  • accepts Android VectorDrawable XML input
  • filters directory-mode XML discovery to real VectorDrawable files only
  • supports svg output by writing the converted SvgDocument directly
  • keeps existing bitmap/PDF/XPS flows on the SKSvg rendering path

4. Documentation updates

The README now includes:

  • direct SKSvg.LoadVectorDrawable(...) usage
  • SvgService.OpenVectorDrawable(...) usage
  • note about SKSvg.Load("file.xml") auto-detection for Android VectorDrawable

Android Contract Validation

This PR adds a test-only validator generated from a pinned Android framework source file:

  • pinned source: android-15.0.0_r1
  • file: frameworks/base/core/res/res/values/attrs.xml

The validator parses the Android VectorDrawable, VectorDrawableGroup, VectorDrawablePath, and VectorDrawableClipPath styleables and uses them to validate:

  • allowed attributes by element
  • enum domains
  • required attributes
  • legal nesting
  • root metric constraints

This gives the test suite a stable Android contract to validate against without adding runtime schema validation cost.

The validator also makes one implementation extension explicit:

  • clip-path.android:fillType

That attribute is supported by the importer and renderer, but it is not part of the pinned AOSP VectorDrawableClipPath styleable. The test contract treats it as an explicit Svg.Skia extension instead of assuming it is standard Android behavior.

Tests

Added model tests covering:

  • root size, viewport, and alpha mapping
  • path paint and alpha mapping
  • ID preservation
  • clip-path generation and wiring
  • clip-path even-odd behavior
  • group matrix transform generation
  • unsupported feature rejection
  • positive root metric validation

Added renderer/API tests covering:

  • SKSvg.LoadVectorDrawable(Stream)
  • path-based .xml auto-detection
  • render parity between VectorDrawable input and equivalent SVG for:
    • filled paths
    • stroked paths
    • clipped groups
    • even-odd clip paths

Added contract tests covering:

  • pinned Android styleable parsing
  • classification of all non-hidden Android VectorDrawable attributes
  • explicit extension handling
  • validation of supported, unsupported, and constrained attributes
  • rejection of unknown Android attributes and invalid nesting

Commit Breakdown

  1. 6336afc5 Add VectorDrawable import support

    • importer, APIs, and core test coverage
  2. 18620b28 Update converter for VectorDrawable files

    • sample converter support and README updates
  3. e7a91218 Add pinned VectorDrawable spec validator

    • test-only Android contract generator/validator and pinned attrs.xml

Verification

Validated with:

  • dotnet format Svg.Skia.slnx --no-restore
  • dotnet build Svg.Skia.slnx -c Release --no-restore
  • dotnet test Svg.Skia.slnx -c Release --no-build

Full solution build and test passed. Existing repository warnings remain, but there were no test failures from this change set.

Fixes #467

@wieslawsoltes wieslawsoltes merged commit a5573eb into master Mar 8, 2026
19 checks passed
@wieslawsoltes wieslawsoltes deleted the feature/vector-drawable-import branch March 8, 2026 21:43
@scottfly189
Copy link
Copy Markdown

Thank you for your excellent work! This is exactly what I wanted.

Thank you in advance! Since I am a Chinese citizen within China and have no foreign exchange payment channels, I cannot donate to you now. If I resolve this problem(exchange payment channels), I will remember to come back and donate. Once again, thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

support Android VectorDrawable XML feature

2 participants