Skip to content

[various] Support SVG filters (blur, offset, feMerge) - #11909

Merged
auto-submit[bot] merged 3 commits into
flutter:mainfrom
edwin-hollen:upstream-svg-filters-mask
Nov 11, 2026
Merged

auto-submit[bot] merged 3 commits into
flutter:mainfrom
edwin-hollen:upstream-svg-filters-mask

Conversation

@edwin-hollen

@edwin-hollen edwin-hollen commented Jun 15, 2026 •

Copy link
Copy Markdown
Contributor

[various] Support SVG filters (blur, offset, feMerge)

Fixes flutter/flutter#158592

This PR introduces support for basic SVG filters (feGaussianBlur, feOffset, and feMerge) to the vector_graphics ecosystem. (Alpha mask support has been split out into a separate PR per review feedback.)

Key Features:

  • Added parsing, resolution, and encoding of SVG filters including feGaussianBlur, feOffset, and feMerge in vector_graphics_compiler.
  • Updated the binary format and vector_graphics_codec to support encoding and decoding paint blurs.
  • Updated vector_graphics to render paint blurs using Flutter's ui.ImageFilter.blur.
  • Enhanced SourceAlpha filters to preserve opacity variations in gradient stops by mapping gradient colors to black while maintaining their alpha values.

Implementation Details:

  • Filter Chaining: Filters are parsed into a directed acyclic graph (DAG) of primitives. The resolver traces these primitives from the filter outputs back to SourceGraphic/SourceAlpha to determine the necessary rendering layers.
  • Multi-layer Filter Resolution: Handles multi-layer filters (e.g. from feMerge) by duplicating the target rendering nodes for each layer in the AST.
  • Text Filter Resolution: Resolves filters at the TextPositionNode level (rather than leaf TextNodes) to maintain correct text chunk alignment and cursor positioning.
  • Nested Filter Propagation: Enhanced nested parent nodes (groups), inner path filters, and text position nodes to correctly inherit and propagate the outer SourceAlpha state down the tree.
  • Blur Scaling: Scales the blur standard deviations by the accumulated transform's scale factors at both the group and path/text levels to ensure correct rendering when scaled (since the compiler bakes geometry transforms at compile time, the blur sigmas must also be scaled to match).
  • Compiler Optimizer & Tessellator Compatibility:
    • Preserves blurSigmaX/blurSigmaY when TessellationVisitor and PathOps convert PathNodes to VerticesNodes.
    • Prevents MaskingOptimizer, ClippingOptimizer, and OverdrawOptimizer from collapsing or intersecting paths that carry a blur filter (since blurred paint extends beyond geometric path bounds).
  • Spec Compliance:
    • Supports both comma and space-separated stdDeviation values.
    • Defaults omitted stdDeviation attributes to 0.0 (as per SVG spec).
    • Automatically resolves default in attributes for feMergeNodes (falling back to the previous sibling primitive's result or SourceGraphic).
    • Preserves original fill/stroke opacity when applying SourceAlpha filters.
    • Handles self-closing <feMerge /> elements.
  • Robustness, Performance & Optimizations:
    • Added cycle detection during filter tracing to prevent stack overflow on circular filter references.
    • Skips rendering node recreation for filter layers that do not affect the paint (e.g. plain SourceGraphic branches in a merge).
    • Wrapped current layer state restoration in try-finally blocks inside parent node and text position node visitors to guarantee robust recovery in case of exceptions.
    • Caches blackened gradients in ResolvingVisitor to prevent redundant object allocations for shared SVG gradients.
    • Guarded against setting paint imageFilter when blur standard deviations are 0.0 to avoid unnecessary rendering overhead in Flutter.
    • Defensively clamped blur standard deviations to non-negative values in the rendering listener to prevent crashes when processing malformed SVG files.

Pre-Review Checklist

If you need help, consider asking for advice on the #hackers-new channel on Discord.

Note: The Flutter team is currently trialing the use of Gemini Code Assist for GitHub. Comments from the gemini-code-assist bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

TAG=agy
CONV=27cb188a-9ad9-4434-8918-8ef71bdba17c

Footnotes

  1. Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling. ↩ ↩2

@github-actions github-actions Bot added p: vector_graphics triage-engine Should be looked at in engine triage labels Jun 15, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for SVG filters, specifically blur and offset, and alpha masks across the vector_graphics, vector_graphics_codec, and vector_graphics_compiler packages. It updates the parser to handle , feGaussianBlur, feOffset, and feMerge elements, adds encoding/decoding for paint blur commands, and implements rendering support via ImageFilter.blur. The review feedback highlights several areas for improvement: handling comma-separated values in stdDeviation, defaulting omitted in attributes on feMergeNode, preserving the original element's opacity when applying isSourceAlpha filters, and implementing cycle detection during recursive filter tracing to prevent stack overflows.

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch 2 times, most recently from 0453cc0 to 5955e54 Compare June 15, 2026 18:19
@edwin-hollen
edwin-hollen marked this pull request as draft June 15, 2026 18:23
@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from 5955e54 to 5b44d76 Compare June 15, 2026 18:23
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for SVG filters (specifically Gaussian blur) and alpha masks (mask-type=alpha) across the vector graphics packages, including updates to the codec, compiler, and renderer, along with an interactive gallery example. Feedback on the changes highlights a redundant check in the filter parser, a limitation in parsing filters where feMerge is not the final operation, and incomplete support for multi-layer filters on group nodes (ParentNode).

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from 5b44d76 to a6f0287 Compare June 15, 2026 18:35
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from a6f0287 to ce01413 Compare June 15, 2026 18:36
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for SVG filters (specifically Gaussian blur) and alpha masks across the vector graphics packages. Key changes include adding a paint blur command to the codec, parsing filter primitives (feGaussianBlur, feOffset, feMerge) in the compiler, resolving filter layers in the resolver visitor, and applying image filters to paints in the renderer. Additionally, the example app is updated with a filter and mask gallery. The review feedback highlights three areas for improvement: using the ui. prefix for ImageFilter to prevent compilation errors, resolving a transformation mismatch in visitTextPositionNode that could cause layout misalignment, and using ByteData.sublistView instead of asByteData() for safer byte buffer handling.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for SVG filters (specifically Gaussian blur, offset, and merge) and alpha masks across the vector graphics packages, including the compiler, codec, and runtime renderer. It also updates the example application with a gallery demonstrating these features. The reviewer feedback suggests handling trailing delimiters in stdDeviation parsing to prevent invalidating the filter, and combining chained Gaussian blurs using the square root of the sum of squares rather than linear addition.

@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from ce01413 to 53a75e8 Compare June 15, 2026 18:40

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for SVG filters, specifically blur and multi-layer filters, and alpha masks (mask-type=alpha) across the vector_graphics package, compiler, and codec. It also adds a filter and mask gallery to the example application along with corresponding tests. Review feedback points out three areas for improvement: handling single-layer filters with offsets at the TextPositionNode level to avoid text positioning bugs, ensuring single-layer filters with isSourceAlpha enabled are not ignored during parsing, and using the ui. prefix for ImageFilter.blur in the listener for import consistency.

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch 2 times, most recently from f4e0eff to 98a6f03 Compare June 15, 2026 18:45
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for SVG filters (such as Gaussian blur and offset) and alpha masks across the vector graphics packages. It updates the compiler to parse and resolve these filters, adds encoding and decoding support in the codec, and implements paint blur rendering in the listener. An issue was identified in the resolver where multi-layer filters on text nodes only process the first layer, ignoring subsequent layers, and a fix was suggested to resolve all layers into a parent node.

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from 98a6f03 to d02df90 Compare June 15, 2026 18:49
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from d02df90 to f51ca1b Compare June 15, 2026 18:54
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for SVG filters (specifically Gaussian blur, offsets, and multi-layer merging) and alpha masks across the vector graphics packages. Key changes include codec updates to handle paint blur commands, XML parsing for filter and mask attributes, and resolving these filters into paint properties or layers during compilation. Feedback on these changes points out a missing dart:math import in the parser, opportunities to optimize performance by caching a regular expression and avoiding redundant node recreation when the current filter layer has no visual effect, and a suggestion to refactor duplicated paint-creation logic into a helper method.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for SVG filters (such as blur and offset) and alpha masks across the vector_graphics, vector_graphics_codec, and vector_graphics_compiler packages. It adds the capability to parse, encode, decode, and render these filters and masks, along with corresponding tests and gallery examples. Feedback on the changes suggests defaulting parsedX and parsedY to 0.0 when stdDeviation is omitted on a <feGaussianBlur> element to comply with SVG specifications and avoid breaking the filter reference chain.

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from f51ca1b to c525511 Compare June 15, 2026 19:01
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

/gemini review

@flutter-dashboard flutter-dashboard Bot removed the CICD Run CI/CD label Oct 6, 2026
@edwin-hollen
edwin-hollen requested a review from walley892 October 6, 2026 18:34
@edwin-hollen
edwin-hollen marked this pull request as draft October 6, 2026 18:47
auto-submit Bot pushed a commit that referenced this pull request Oct 12, 2026
#13025)

[vector_graphics_compiler] Support SVG alpha masks (`mask-type="alpha"`)

Fixes flutter/flutter#158734

This PR adds support for SVG alpha masks (`mask-type="alpha"` and `style="mask-type: alpha"`) in `vector_graphics_compiler`, split out from #11909 per review feedback.

### Summary of Changes
* **SVG Parser & AST (`vector_graphics_compiler`)**:
  * Parses the `mask-type` attribute (and inline `style="mask-type: ..."` property) on `<mask>` elements in `SvgParser`.
  * Propagates `isAlphaMask` through `ResolvedMaskNode` and `MaskNode`.
  * Emits `BlendMode.dstIn` for alpha masks instead of `BlendMode.srcIn` with a luminance-to-alpha color filter matrix (`BlendMode.modulate`).
* **MaskingOptimizer Compatibility**:
  * Updates `MaskingOptimizer` so single-path masks using gradients with translucent stops (`stop-opacity < 1.0`) are preserved rather than replaced with solid geometry intersection (which previously discarded the gradient's alpha channel).

## Pre-Review Checklist

**Note**: The Flutter team is currently trialing the use of [Gemini Code Assist for GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code). Comments from the `gemini-code-assist` bot should not be taken as authoritative feedback from the Flutter team. If you find its comments useful you can update your code accordingly, but if you are unsure or disagree with the feedback, please feel free to wait for a Flutter team member's review for guidance on which automated comments should be addressed.

[^1]: Regular contributors who have demonstrated familiarity with the repository guidelines only need to comment if the PR is not auto-exempted by repo tooling.

TAG=agy
CONV=1bad96cc-81aa-438f-98f6-cb909289144a
auto-submit Bot pushed a commit that referenced this pull request Oct 14, 2026
…lur commands (#13148)

Adds a new `_paintBlurTag` command (`writePaintBlur` / `onPaintBlur`) to `vector_graphics_codec` (`1.2.0`) to support encoding and decoding Gaussian blur image filters (`sigmaX`, `sigmaY`) alongside paint records.

This is split out from #11909 so the codec changes can land and be published first.

Part of flutter/flutter#158592

## Pre-Review Checklist
@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch from 6ec752f to bf5d899 Compare October 26, 2026 14:53
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

Rebased onto main. Keeping in draft until vector_graphics_codec 1.2.0 (#13148) is published to pub.dev.

@gaaclarke
gaaclarke marked this pull request as ready for review October 26, 2026 16:38
@gaaclarke
gaaclarke removed their request for review October 26, 2026 16:39
@gaaclarke

Copy link
Copy Markdown
Member

I put this in review officially and removed myself as a reviewer, @walley892 is working on this one as the first reviewer.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for SVG filters (feGaussianBlur, feOffset, feMerge, and feMergeNode) to the vector_graphics and vector_graphics_compiler packages. The changes introduce SVG filter parsing, update paint attributes to store blur parameters, scale blur standard deviations based on transform scale factors, and adjust clipping, masking, and overdraw optimizers to handle blurred paths correctly. The binary encoder and decoder are also updated to support paint blur instructions, package versions are bumped, and comprehensive tests are added. There are no review comments, and I have no feedback to provide.

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch 2 times, most recently from 7b02dc3 to aee6249 Compare October 29, 2026 17:53

@walley892 walley892 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still waiting on the codec change to hit pub.dev to run CI, but I've got a few comments to start us off

return;
}

static void filter(SvgParser parserState, bool warningsAsErrors) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now, this supports feMerge, feGaussianBlur, feOffset and feMergeNode, and ignores other filter primitives.

This creates a regression compared to today's behavior when mixing supported and unsupported primitives. For example:

<svg width="140" height="140" viewBox="0 0 140 140" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d_1_2)">
<rect x="20" y="16" width="100" height="100" rx="12" fill="#4F46E5"/>
</g>
<defs>
<filter id="filter0_d_1_2" x="0" y="0" width="140" height="140" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="5"/>
<feComposite in2="hardAlpha" operator="out"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_1_2"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_1_2" result="shape"/>
</filter>
</defs>
</svg>

Should render as a drop shadow, but instead just creates a blurred rect

Image

Maybe if a filter contains unsupported primitives - we just fail it and emit an error?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that makes sense. I updated filter to fail and emit an unhandled element error if it contains unsupported primitives, and added a test for it.

Comment thread packages/vector_graphics/pubspec.yaml Outdated
repository: https://github.com/flutter/packages/tree/main/packages/vector_graphics
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+vector_graphics%22
version: 1.2.5
version: 1.2.6

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this a full minor version bump - 1.3.0

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done, bumped vector_graphics to 1.3.0.

Comment on lines +546 to +548
if (parserState._currentStartElement?.isSelfClosing ?? false) {
return;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this for?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, it's not needed anymore, it was an unrelated guard for self closing clipPath elements. I removed it.

Comment on lines +96 to +100
final children = <Node>[];
for (final SvgFilterLayer layer in filter.layers) {
children.add(_resolveParentNodeForLayer(parentNode, nextTransform, layer));
}
return ParentNode(SvgAttributes.empty, children: children);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This creates a new savelayer for each layer, which causes the opacity to be applied to each layer separately instead of to the result of the entire filter. For example:

<svg width="140" height="140" viewBox="0 0 140 140" xmlns="http://www.w3.org/2000/svg">
  <filter id="drop" x="-50%" y="-50%" width="200%" height="200%">
    <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/>
    <feOffset in="blur" dx="10" dy="10" result="shadow"/>
    <feMerge>
      <feMergeNode in="shadow"/>
      <feMergeNode in="SourceGraphic"/>
    </feMerge>
  </filter>
  <g opacity="0.5" filter="url(#drop)">
    <rect x="20" y="20" width="90" height="90" fill="#DC2626"/>
  </g>
</svg>
Image

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I realized I didn't have a test for this either. I updated visitParentNode to handle that case, and a test to cover it.

@edwin-hollen
edwin-hollen force-pushed the upstream-svg-filters-mask branch 2 times, most recently from 867b452 to 23a9dab Compare November 3, 2026 15:01
@edwin-hollen

Copy link
Copy Markdown
Contributor Author

@walley892 it looks like vector_graphics_codec 1.2.0 is held up because the release workflow run (https://github.com/flutter/packages/actions/runs/38633635933) hit a timeout (flutter/flutter#194870).

@flar flar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I apparently never submitted these review comments.

@override
void onPaintBlur(int paintId, double sigmaX, double sigmaY) {
final clampedX = sigmaX < 0.0 ? 0.0 : sigmaX;
final clampedY = sigmaY < 0.0 ? 0.0 : sigmaY;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 2 lines can protect against NaN values by reversing the comparison.

sigma > 0.0 ? sigma : 0.0 produces 0.0 for NaN
sigma < 0.0 ? 0.0 : sigma produces NaN for NaN.

NaN values become a NOP here instead of being passed along to future code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, switched both checks to > 0.0 so NaN clamps to 0.0.

expect(drawPath.memberName, #drawPath);
final paint = drawPath.positionalArguments[1] as ui.Paint;
expect(paint.imageFilter, isNull);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add tests for one or both being NaN.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added tests covering NaN for sigmaX, sigmaY, and both.

@flar flar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New changes LGTM

@walley892 walley892 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM assuming CI passes

@edwin-hollen

Copy link
Copy Markdown
Contributor Author

Rebased onto main to resolve the vector_graphics 1.2.7 conflict.

@walley892 @flar could one of you re-trigger CI (and add autosubmit) on the new commit? Also, @gaaclarke could you dismiss your Aug 19 CHANGES_REQUESTED review since alpha masks were split out and merged in #13025? Thanks!

@gaaclarke

Copy link
Copy Markdown
Member

Also, @gaaclarke could you dismiss your Aug 19 CHANGES_REQUESTED review since alpha masks were split out and merged in #13025? Thanks!

I don't have a changes requested review on here.

@auto-submit

auto-submit Bot commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

autosubmit label was removed for flutter/packages/11909, because This PR has not met approval requirements for merging. Changes were requested by {gaaclarke}, please make the needed changes and resubmit this PR.
The PR author is not a member of flutter-hackers and needs 1 more review(s) in order to merge this PR.

  • Merge guidelines: A PR needs at least one approved review if the author is already part of flutter-hackers or two member reviews if the author is not a member of flutter-hackers before re-applying the autosubmit label. Reviewers: If you left a comment approving, please use the "approve" review action instead.

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

Labels

autosubmit Merge PR when tree becomes green via auto submit App CICD Run CI/CD p: vector_graphics triage-engine Should be looked at in engine triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[flutter_svg] Add (some) support for blur effect

8 participants