This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
Allow Tile mode for blur filter and add new decal TileMode #22982
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3137,10 +3137,11 @@ class _ColorFilter extends NativeFieldWrapperClass2 { | |
| /// this class as a child layer filter. | ||
| abstract class ImageFilter { | ||
| /// Creates an image filter that applies a Gaussian blur. | ||
| factory ImageFilter.blur({ double sigmaX = 0.0, double sigmaY = 0.0 }) { | ||
| factory ImageFilter.blur({ double sigmaX = 0.0, double sigmaY = 0.0, TileMode tileMode = TileMode.clamp }) { | ||
| assert(sigmaX != null); // ignore: unnecessary_null_comparison | ||
| assert(sigmaY != null); // ignore: unnecessary_null_comparison | ||
| return _GaussianBlurImageFilter(sigmaX: sigmaX, sigmaY: sigmaY); | ||
| assert(tileMode != null); // ignore: unnecessary_null_comparison | ||
| return _GaussianBlurImageFilter(sigmaX: sigmaX, sigmaY: sigmaY, tileMode: tileMode); | ||
| } | ||
|
|
||
| /// Creates an image filter that applies a matrix transformation. | ||
|
|
@@ -3206,29 +3207,40 @@ class _MatrixImageFilter implements ImageFilter { | |
| } | ||
|
|
||
| class _GaussianBlurImageFilter implements ImageFilter { | ||
| _GaussianBlurImageFilter({ required this.sigmaX, required this.sigmaY }); | ||
| _GaussianBlurImageFilter({ required this.sigmaX, required this.sigmaY, required this.tileMode }); | ||
|
|
||
| final double sigmaX; | ||
| final double sigmaY; | ||
| final TileMode tileMode; | ||
|
|
||
| // MakeBlurFilter | ||
| late final _ImageFilter nativeFilter = _ImageFilter.blur(this); | ||
| @override | ||
| _ImageFilter _toNativeImageFilter() => nativeFilter; | ||
|
|
||
| String get _modeString { | ||
| switch(tileMode) { | ||
| case TileMode.clamp: return 'clamp'; | ||
| case TileMode.mirror: return 'mirror'; | ||
| case TileMode.repeated: return 'repeated'; | ||
| case TileMode.decal: return 'decal'; | ||
| } | ||
| } | ||
|
|
||
| @override | ||
| String get _shortDescription => 'blur($sigmaX, $sigmaY)'; | ||
| String get _shortDescription => 'blur($sigmaX, $sigmaY, $_modeString)'; | ||
|
|
||
| @override | ||
| String toString() => 'ImageFilter.blur($sigmaX, $sigmaY)'; | ||
| String toString() => 'ImageFilter.blur($sigmaX, $sigmaY, $_modeString)'; | ||
|
|
||
| @override | ||
| bool operator ==(Object other) { | ||
| if (other.runtimeType != runtimeType) | ||
| return false; | ||
| return other is _GaussianBlurImageFilter | ||
| && other.sigmaX == sigmaX | ||
| && other.sigmaY == sigmaY; | ||
| && other.sigmaY == sigmaY | ||
| && other.tileMode == tileMode; | ||
| } | ||
|
|
||
| @override | ||
|
|
@@ -3278,9 +3290,9 @@ class _ImageFilter extends NativeFieldWrapperClass2 { | |
| : assert(filter != null), // ignore: unnecessary_null_comparison | ||
| creator = filter { // ignore: prefer_initializing_formals | ||
| _constructor(); | ||
| _initBlur(filter.sigmaX, filter.sigmaY); | ||
| _initBlur(filter.sigmaX, filter.sigmaY, filter.tileMode.index); | ||
| } | ||
| void _initBlur(double sigmaX, double sigmaY) native 'ImageFilter_initBlur'; | ||
| void _initBlur(double sigmaX, double sigmaY, int tileMode) native 'ImageFilter_initBlur'; | ||
|
|
||
| /// Creates an image filter that applies a matrix transformation. | ||
| /// | ||
|
|
@@ -3330,14 +3342,22 @@ class Shader extends NativeFieldWrapperClass2 { | |
| Shader._(); | ||
| } | ||
|
|
||
| /// Defines what happens at the edge of the gradient. | ||
| /// Defines what happens at the edge of a gradient or the sampling of a source image | ||
| /// in an [ImageFilter]. | ||
| /// | ||
| /// A gradient is defined along a finite inner area. In the case of a linear | ||
| /// gradient, it's between the parallel lines that are orthogonal to the line | ||
| /// drawn between two points. In the case of radial gradients, it's the disc | ||
| /// that covers the circle centered on a particular point up to a given radius. | ||
| /// | ||
| /// This enum is used to define how the gradient should paint the regions | ||
| /// An image filter reads source samples from a source image and performs operations | ||
| /// on those samples to produce a result image. An image defines color samples only | ||
| /// for pixels within the bounds of the image but some filter operations, such as a blur | ||
| /// filter, read samples over a wide area to compute the output for a given pixel. Such | ||
| /// a filter would need to combine samples from inside the image with hypothetical | ||
| /// color values from outside the image. | ||
| /// | ||
| /// This enum is used to define how the gradient or image filter should treat the regions | ||
| /// outside that defined inner area. | ||
| /// | ||
| /// See also: | ||
|
|
@@ -3349,36 +3369,60 @@ class Shader extends NativeFieldWrapperClass2 { | |
| /// * [dart:ui.Gradient], the low-level class used when dealing with the | ||
| /// [Paint.shader] property directly, with its [Gradient.linear] and | ||
| /// [Gradient.radial] constructors. | ||
| // These enum values must be kept in sync with SkShader::TileMode. | ||
| /// * [dart:ui.ImageFilter.blur], an ImageFilter that may sometimes need to | ||
| /// read samples from outside an image to combine with the pixels near the | ||
| /// edge of the image. | ||
| // These enum values must be kept in sync with SkTileMode. | ||
| enum TileMode { | ||
| /// Edge is clamped to the final color. | ||
| /// Samples beyond the edge are clamped to the nearest color in the defined inner area. | ||
| /// | ||
| /// A gradient will paint all the regions outside the inner area with the | ||
| /// color at the end of the color stop list closest to that region. | ||
| /// | ||
| /// The gradient will paint the all the regions outside the inner area with | ||
| /// the color of the point closest to that region. | ||
| /// An image filter will substitute the nearest edge pixel for any samples taken from | ||
| /// outside its source image. | ||
| /// | ||
| ///  | ||
| ///  | ||
| clamp, | ||
|
|
||
| /// Edge is repeated from first color to last. | ||
| /// Samples beyond the edge are repeated from the far end of the defined area. | ||
| /// | ||
| /// This is as if the stop points from 0.0 to 1.0 were then repeated from 1.0 | ||
| /// to 2.0, 2.0 to 3.0, and so forth (and for linear gradients, similarly from | ||
| /// -1.0 to 0.0, -2.0 to -1.0, etc). | ||
| /// For a gradient, this technique is as if the stop points from 0.0 to 1.0 were then | ||
| /// repeated from 1.0 to 2.0, 2.0 to 3.0, and so forth (and for linear gradients, similarly | ||
| /// from -1.0 to 0.0, -2.0 to -1.0, etc). | ||
| /// | ||
| /// An image filter will treat its source image as if it were tiled across the enlarged | ||
| /// sample space from which it reads, each tile in the same orientation as the base image. | ||
| /// | ||
| ///  | ||
| ///  | ||
| repeated, | ||
|
|
||
| /// Edge is mirrored from last color to first. | ||
| /// Samples beyond the edge are mirrored back and forth across the defined area. | ||
| /// | ||
| /// This is as if the stop points from 0.0 to 1.0 were then repeated backwards | ||
| /// from 2.0 to 1.0, then forwards from 2.0 to 3.0, then backwards again from | ||
| /// 4.0 to 3.0, and so forth (and for linear gradients, similarly from in the | ||
| /// For a gradient, this technique is as if the stop points from 0.0 to 1.0 were then | ||
| /// repeated backwards from 2.0 to 1.0, then forwards from 2.0 to 3.0, then backwards | ||
| /// again from 4.0 to 3.0, and so forth (and for linear gradients, similarly in the | ||
| /// negative direction). | ||
| /// | ||
| /// An image filter will treat its source image as tiled in an alternating forwards and | ||
| /// backwards or upwards and downwards direction across the sample space from which | ||
| /// it is reading. | ||
| /// | ||
| ///  | ||
| ///  | ||
| mirror, | ||
|
|
||
| /// Samples beyond the edge are treated as transparent black. | ||
| /// | ||
| /// A gradient will render transparency over any region that is outside the circle of a | ||
| /// radial gradient or outside the parallel lines that define the inner area of a linear | ||
| /// gradient. | ||
| /// | ||
| /// An image filter will substitute transparent black for any sample it must read from | ||
| /// outside its source image. | ||
| decal, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess decal is as good a name for this as any, and has the advantage of matching Skia. |
||
| } | ||
|
|
||
| Int32List _encodeColorList(List<Color> colors) { | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,4 +10,5 @@ enum TileMode { | |
| clamp, | ||
| repeated, | ||
| mirror, | ||
| decal, | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't forget to add the new image, too. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plan was to add that as soon as it propagates to the framework and I can modify the built assets. I also plan to add equivalent ImageFilter.blur example images to all of the TileMode values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I landed new assets today which included the assets for decal. (I forgot about ImageFilter.blur examples, sorry, so if they haven't been added yet they're still missing.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was that just for the gradient? I have been waiting to update these assets until Skia fixes bugs in the tile mode handling for the ImageFilter.blur(). It was supposed to go in a few days after this PR, but the fix has been re-un-re-verted since then and still hasn't landed and rolled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tracking the blur/TileMode doc image issue in flutter/flutter#74367