Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
e872177c
E
engine
项目概览
weixin_43355755
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
e872177c
编写于
11月 12, 2020
作者:
L
LongCatIsLooong
提交者:
GitHub
11月 12, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Exposing ColorFilter to ImageFilter conversion and Compose() (#20309)
上级
47f9e134
变更
15
隐藏空白更改
内联
并排
Showing
15 changed file
with
797 addition
and
321 deletion
+797
-321
lib/ui/painting.dart
lib/ui/painting.dart
+182
-86
lib/ui/painting/image_filter.cc
lib/ui/painting/image_filter.cc
+18
-5
lib/ui/painting/image_filter.h
lib/ui/painting/image_filter.h
+3
-0
lib/web_ui/lib/src/engine/bitmap_canvas.dart
lib/web_ui/lib/src/engine/bitmap_canvas.dart
+10
-12
lib/web_ui/lib/src/engine/canvaskit/canvas.dart
lib/web_ui/lib/src/engine/canvaskit/canvas.dart
+2
-2
lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
+10
-0
lib/web_ui/lib/src/engine/canvaskit/color_filter.dart
lib/web_ui/lib/src/engine/canvaskit/color_filter.dart
+133
-48
lib/web_ui/lib/src/engine/canvaskit/image_filter.dart
lib/web_ui/lib/src/engine/canvaskit/image_filter.dart
+61
-13
lib/web_ui/lib/src/engine/canvaskit/painting.dart
lib/web_ui/lib/src/engine/canvaskit/painting.dart
+18
-13
lib/web_ui/lib/src/engine/color_filter.dart
lib/web_ui/lib/src/engine/color_filter.dart
+4
-81
lib/web_ui/lib/src/engine/html/color_filter.dart
lib/web_ui/lib/src/engine/html/color_filter.dart
+58
-61
lib/web_ui/lib/src/ui/painting.dart
lib/web_ui/lib/src/ui/painting.dart
+6
-0
lib/web_ui/test/canvaskit/canvaskit_api_test.dart
lib/web_ui/test/canvaskit/canvaskit_api_test.dart
+20
-0
lib/web_ui/test/canvaskit/filter_test.dart
lib/web_ui/test/canvaskit/filter_test.dart
+96
-0
testing/dart/image_filter_test.dart
testing/dart/image_filter_test.dart
+176
-0
未找到文件。
lib/ui/painting.dart
浏览文件 @
e872177c
...
@@ -2900,7 +2900,7 @@ class MaskFilter {
...
@@ -2900,7 +2900,7 @@ class MaskFilter {
///
///
/// Instances of this class are used with [Paint.colorFilter] on [Paint]
/// Instances of this class are used with [Paint.colorFilter] on [Paint]
/// objects.
/// objects.
class
ColorFilter
{
class
ColorFilter
implements
ImageFilter
{
/// Creates a color filter that applies the blend mode given as the second
/// Creates a color filter that applies the blend mode given as the second
/// argument. The source color is the one given as the first argument, and the
/// argument. The source color is the one given as the first argument, and the
/// destination color is the one from the layer being composited.
/// destination color is the one from the layer being composited.
...
@@ -2912,7 +2912,7 @@ class ColorFilter {
...
@@ -2912,7 +2912,7 @@ class ColorFilter {
:
_color
=
color
,
:
_color
=
color
,
_blendMode
=
blendMode
,
_blendMode
=
blendMode
,
_matrix
=
null
,
_matrix
=
null
,
_type
=
_TypeMode
;
_type
=
_
k
TypeMode
;
/// Construct a color filter that transforms a color by a 5x5 matrix, where
/// Construct a color filter that transforms a color by a 5x5 matrix, where
/// the fifth row is implicitly added in an identity configuration.
/// the fifth row is implicitly added in an identity configuration.
...
@@ -2978,7 +2978,7 @@ class ColorFilter {
...
@@ -2978,7 +2978,7 @@ class ColorFilter {
:
_color
=
null
,
:
_color
=
null
,
_blendMode
=
null
,
_blendMode
=
null
,
_matrix
=
matrix
,
_matrix
=
matrix
,
_type
=
_TypeMatrix
;
_type
=
_
k
TypeMatrix
;
/// Construct a color filter that applies the sRGB gamma curve to the RGB
/// Construct a color filter that applies the sRGB gamma curve to the RGB
/// channels.
/// channels.
...
@@ -2986,7 +2986,7 @@ class ColorFilter {
...
@@ -2986,7 +2986,7 @@ class ColorFilter {
:
_color
=
null
,
:
_color
=
null
,
_blendMode
=
null
,
_blendMode
=
null
,
_matrix
=
null
,
_matrix
=
null
,
_type
=
_TypeLinearToSrgbGamma
;
_type
=
_
k
TypeLinearToSrgbGamma
;
/// Creates a color filter that applies the inverse of the sRGB gamma curve
/// Creates a color filter that applies the inverse of the sRGB gamma curve
/// to the RGB channels.
/// to the RGB channels.
...
@@ -2994,7 +2994,7 @@ class ColorFilter {
...
@@ -2994,7 +2994,7 @@ class ColorFilter {
:
_color
=
null
,
:
_color
=
null
,
_blendMode
=
null
,
_blendMode
=
null
,
_matrix
=
null
,
_matrix
=
null
,
_type
=
_TypeSrgbToLinearGamma
;
_type
=
_
k
TypeSrgbToLinearGamma
;
final
Color
?
_color
;
final
Color
?
_color
;
final
BlendMode
?
_blendMode
;
final
BlendMode
?
_blendMode
;
...
@@ -3002,55 +3002,77 @@ class ColorFilter {
...
@@ -3002,55 +3002,77 @@ class ColorFilter {
final
int
_type
;
final
int
_type
;
// The type of SkColorFilter class to create for Skia.
// The type of SkColorFilter class to create for Skia.
static
const
int
_TypeMode
=
1
;
// MakeModeFilter
static
const
int
_
k
TypeMode
=
1
;
// MakeModeFilter
static
const
int
_TypeMatrix
=
2
;
// MakeMatrixFilterRowMajor255
static
const
int
_
k
TypeMatrix
=
2
;
// MakeMatrixFilterRowMajor255
static
const
int
_TypeLinearToSrgbGamma
=
3
;
// MakeLinearToSRGBGamma
static
const
int
_
k
TypeLinearToSrgbGamma
=
3
;
// MakeLinearToSRGBGamma
static
const
int
_TypeSrgbToLinearGamma
=
4
;
// MakeSRGBToLinearGamma
static
const
int
_
k
TypeSrgbToLinearGamma
=
4
;
// MakeSRGBToLinearGamma
// SkImageFilters::ColorFilter
@override
@override
bool
operator
==(
Object
other
)
{
_ImageFilter
_toNativeImageFilter
()
=>
_ImageFilter
.
fromColorFilter
(
this
);
return
other
is
ColorFilter
&&
other
.
_type
==
_type
&&
_listEquals
<
double
>(
other
.
_matrix
,
_matrix
)
&&
other
.
_color
==
_color
&&
other
.
_blendMode
==
_blendMode
;
}
_ColorFilter
?
_toNativeColorFilter
()
{
_ColorFilter
?
_toNativeColorFilter
()
{
switch
(
_type
)
{
switch
(
_type
)
{
case
_TypeMode:
case
_
k
TypeMode:
if
(
_color
==
null
||
_blendMode
==
null
)
{
if
(
_color
==
null
||
_blendMode
==
null
)
{
return
null
;
return
null
;
}
}
return
_ColorFilter
.
mode
(
this
);
return
_ColorFilter
.
mode
(
this
);
case
_TypeMatrix:
case
_
k
TypeMatrix:
if
(
_matrix
==
null
)
{
if
(
_matrix
==
null
)
{
return
null
;
return
null
;
}
}
assert
(
_matrix
!.
length
==
20
,
'Color Matrix must have 20 entries.'
);
assert
(
_matrix
!.
length
==
20
,
'Color Matrix must have 20 entries.'
);
return
_ColorFilter
.
matrix
(
this
);
return
_ColorFilter
.
matrix
(
this
);
case
_TypeLinearToSrgbGamma:
case
_
k
TypeLinearToSrgbGamma:
return
_ColorFilter
.
linearToSrgbGamma
(
this
);
return
_ColorFilter
.
linearToSrgbGamma
(
this
);
case
_TypeSrgbToLinearGamma:
case
_
k
TypeSrgbToLinearGamma:
return
_ColorFilter
.
srgbToLinearGamma
(
this
);
return
_ColorFilter
.
srgbToLinearGamma
(
this
);
default
:
default
:
throw
StateError
(
'Unknown mode
$_type
for ColorFilter.'
);
throw
StateError
(
'Unknown mode
$_type
for ColorFilter.'
);
}
}
}
}
@override
bool
operator
==(
Object
other
)
{
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
return
other
is
ColorFilter
&&
other
.
_type
==
_type
&&
_listEquals
<
double
>(
other
.
_matrix
,
_matrix
)
&&
other
.
_color
==
_color
&&
other
.
_blendMode
==
_blendMode
;
}
@override
@override
int
get
hashCode
=>
hashValues
(
_color
,
_blendMode
,
hashList
(
_matrix
),
_type
);
int
get
hashCode
=>
hashValues
(
_color
,
_blendMode
,
hashList
(
_matrix
),
_type
);
@override
String
get
_shortDescription
{
switch
(
_type
)
{
case
_kTypeMode:
return
'ColorFilter.mode(
$_color
,
$_blendMode
)'
;
case
_kTypeMatrix:
return
'ColorFilter.matrix(
$_matrix
)'
;
case
_kTypeLinearToSrgbGamma:
return
'ColorFilter.linearToSrgbGamma()'
;
case
_kTypeSrgbToLinearGamma:
return
'ColorFilter.srgbToLinearGamma()'
;
default
:
return
'unknow ColorFilter'
;
}
}
@override
@override
String
toString
()
{
String
toString
()
{
switch
(
_type
)
{
switch
(
_type
)
{
case
_TypeMode:
case
_
k
TypeMode:
return
'ColorFilter.mode(
$_color
,
$_blendMode
)'
;
return
'ColorFilter.mode(
$_color
,
$_blendMode
)'
;
case
_TypeMatrix:
case
_
k
TypeMatrix:
return
'ColorFilter.matrix(
$_matrix
)'
;
return
'ColorFilter.matrix(
$_matrix
)'
;
case
_TypeLinearToSrgbGamma:
case
_
k
TypeLinearToSrgbGamma:
return
'ColorFilter.linearToSrgbGamma()'
;
return
'ColorFilter.linearToSrgbGamma()'
;
case
_TypeSrgbToLinearGamma:
case
_
k
TypeSrgbToLinearGamma:
return
'ColorFilter.srgbToLinearGamma()'
;
return
'ColorFilter.srgbToLinearGamma()'
;
default
:
default
:
return
'Unknown ColorFilter type. This is an error. If you
\'
re seeing this, please file an issue at https://github.com/flutter/flutter/issues/new.'
;
return
'Unknown ColorFilter type. This is an error. If you
\'
re seeing this, please file an issue at https://github.com/flutter/flutter/issues/new.'
;
...
@@ -3067,27 +3089,27 @@ class ColorFilter {
...
@@ -3067,27 +3089,27 @@ class ColorFilter {
class
_ColorFilter
extends
NativeFieldWrapperClass2
{
class
_ColorFilter
extends
NativeFieldWrapperClass2
{
_ColorFilter
.
mode
(
this
.
creator
)
_ColorFilter
.
mode
(
this
.
creator
)
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
creator
.
_type
==
ColorFilter
.
_TypeMode
)
{
assert
(
creator
.
_type
==
ColorFilter
.
_
k
TypeMode
)
{
_constructor
();
_constructor
();
_initMode
(
creator
.
_color
!.
value
,
creator
.
_blendMode
!.
index
);
_initMode
(
creator
.
_color
!.
value
,
creator
.
_blendMode
!.
index
);
}
}
_ColorFilter
.
matrix
(
this
.
creator
)
_ColorFilter
.
matrix
(
this
.
creator
)
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
creator
.
_type
==
ColorFilter
.
_TypeMatrix
)
{
assert
(
creator
.
_type
==
ColorFilter
.
_
k
TypeMatrix
)
{
_constructor
();
_constructor
();
_initMatrix
(
Float32List
.
fromList
(
creator
.
_matrix
!));
_initMatrix
(
Float32List
.
fromList
(
creator
.
_matrix
!));
}
}
_ColorFilter
.
linearToSrgbGamma
(
this
.
creator
)
_ColorFilter
.
linearToSrgbGamma
(
this
.
creator
)
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
creator
.
_type
==
ColorFilter
.
_TypeLinearToSrgbGamma
)
{
assert
(
creator
.
_type
==
ColorFilter
.
_
k
TypeLinearToSrgbGamma
)
{
_constructor
();
_constructor
();
_initLinearToSrgbGamma
();
_initLinearToSrgbGamma
();
}
}
_ColorFilter
.
srgbToLinearGamma
(
this
.
creator
)
_ColorFilter
.
srgbToLinearGamma
(
this
.
creator
)
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
:
assert
(
creator
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
creator
.
_type
==
ColorFilter
.
_TypeSrgbToLinearGamma
)
{
assert
(
creator
.
_type
==
ColorFilter
.
_
k
TypeSrgbToLinearGamma
)
{
_constructor
();
_constructor
();
_initSrgbToLinearGamma
();
_initSrgbToLinearGamma
();
}
}
...
@@ -3113,80 +3135,134 @@ class _ColorFilter extends NativeFieldWrapperClass2 {
...
@@ -3113,80 +3135,134 @@ class _ColorFilter extends NativeFieldWrapperClass2 {
/// this class as a backdrop filter.
/// this class as a backdrop filter.
/// * [SceneBuilder.pushImageFilter], which is the low-level API for using
/// * [SceneBuilder.pushImageFilter], which is the low-level API for using
/// this class as a child layer filter.
/// this class as a child layer filter.
class
ImageFilter
{
abstract
class
ImageFilter
{
/// Creates an image filter that applies a Gaussian blur.
/// Creates an image filter that applies a Gaussian blur.
ImageFilter
.
blur
({
double
sigmaX
=
0.0
,
double
sigmaY
=
0.0
})
factory
ImageFilter
.
blur
({
double
sigmaX
=
0.0
,
double
sigmaY
=
0.0
})
{
:
assert
(
sigmaX
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
sigmaX
!=
null
);
// ignore: unnecessary_null_comparison
assert
(
sigmaY
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
sigmaY
!=
null
);
// ignore: unnecessary_null_comparison
_data
=
_makeList
(
sigmaX
,
sigmaY
),
return
_GaussianBlurImageFilter
(
sigmaX:
sigmaX
,
sigmaY:
sigmaY
);
_filterQuality
=
null
,
}
_type
=
_kTypeBlur
;
/// Creates an image filter that applies a matrix transformation.
/// Creates an image filter that applies a matrix transformation.
///
///
/// For example, applying a positive scale matrix (see [Matrix4.diagonal3])
/// For example, applying a positive scale matrix (see [Matrix4.diagonal3])
/// when used with [BackdropFilter] would magnify the background image.
/// when used with [BackdropFilter] would magnify the background image.
ImageFilter
.
matrix
(
Float64List
matrix4
,
factory
ImageFilter
.
matrix
(
Float64List
matrix4
,
{
FilterQuality
filterQuality
=
FilterQuality
.
low
})
{
FilterQuality
filterQuality
=
FilterQuality
.
low
})
{
:
assert
(
matrix4
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
matrix4
!=
null
);
// ignore: unnecessary_null_comparison
_data
=
Float64List
.
fromList
(
matrix4
),
assert
(
filterQuality
!=
null
);
// ignore: unnecessary_null_comparison
_filterQuality
=
filterQuality
,
_type
=
_kTypeMatrix
{
if
(
matrix4
.
length
!=
16
)
if
(
matrix4
.
length
!=
16
)
throw
ArgumentError
(
'"matrix4" must have 16 entries.'
);
throw
ArgumentError
(
'"matrix4" must have 16 entries.'
);
return
_MatrixImageFilter
(
data:
Float64List
.
fromList
(
matrix4
),
filterQuality:
filterQuality
);
}
}
static
Float64List
_makeList
(
double
a
,
double
b
)
{
/// Composes the `inner` filter with `outer`, to combine their effects.
final
Float64List
list
=
Float64List
(
2
);
///
list
[
0
]
=
a
;
/// Creates a single [ImageFilter] that when applied, has the same effect as
list
[
1
]
=
b
;
/// subsequently applying `inner` and `outer`, i.e.,
return
list
;
/// result = outer(inner(source)).
factory
ImageFilter
.
compose
({
required
ImageFilter
outer
,
required
ImageFilter
inner
})
{
assert
(
inner
!=
null
&&
outer
!=
null
);
// ignore: unnecessary_null_comparison
return
_ComposeImageFilter
(
innerFilter:
inner
,
outerFilter:
outer
);
}
}
final
Float64List
_data
;
// Converts this to a native SkImageFilter. See the comments of this method in
final
FilterQuality
?
_filterQuality
;
// subclasses for the exact type of SkImageFilter this method converts to.
final
int
_type
;
_ImageFilter
_toNativeImageFilter
();
_ImageFilter
?
_nativeFilter
;
// The type of SkImageFilter class to create for Skia.
// The description text to show when the filter is part of a composite
static
const
int
_kTypeBlur
=
0
;
// MakeBlurFilter
// [ImageFilter] created using [ImageFilter.compose].
static
const
int
_kTypeMatrix
=
1
;
// MakeMatrixFilterRowMajor255
String
get
_shortDescription
;
}
class
_MatrixImageFilter
implements
ImageFilter
{
_MatrixImageFilter
({
required
this
.
data
,
required
this
.
filterQuality
});
final
Float64List
data
;
final
FilterQuality
filterQuality
;
// MakeMatrixFilterRowMajor255
late
final
_ImageFilter
nativeFilter
=
_ImageFilter
.
matrix
(
this
);
@override
_ImageFilter
_toNativeImageFilter
()
=>
nativeFilter
;
@override
String
get
_shortDescription
=>
'matrix(
$data
,
$filterQuality
)'
;
@override
String
toString
()
=>
'ImageFilter.matrix(
$data
,
$filterQuality
)'
;
@override
@override
bool
operator
==(
Object
other
)
{
bool
operator
==(
Object
other
)
{
return
other
is
ImageFilter
if
(
other
.
runtimeType
!=
runtimeType
)
&&
other
.
_type
==
_type
return
false
;
&&
_listEquals
<
double
>(
other
.
_data
,
_data
)
return
other
is
_MatrixImageFilter
&&
other
.
_filterQuality
==
_filterQuality
;
&&
other
.
filterQuality
==
filterQuality
&&
_listEquals
<
double
>(
other
.
data
,
data
);
}
}
_ImageFilter
_toNativeImageFilter
()
=>
_nativeFilter
??=
_makeNativeImageFilter
();
@override
int
get
hashCode
=>
hashValues
(
filterQuality
,
hashList
(
data
));
}
_ImageFilter
_makeNativeImageFilter
()
{
class
_GaussianBlurImageFilter
implements
ImageFilter
{
switch
(
_type
)
{
_GaussianBlurImageFilter
({
required
this
.
sigmaX
,
required
this
.
sigmaY
});
case
_kTypeBlur:
return
_ImageFilter
.
blur
(
this
);
final
double
sigmaX
;
case
_kTypeMatrix:
final
double
sigmaY
;
return
_ImageFilter
.
matrix
(
this
);
default
:
// MakeBlurFilter
throw
StateError
(
'Unknown mode
$_type
for ImageFilter.'
);
late
final
_ImageFilter
nativeFilter
=
_ImageFilter
.
blur
(
this
);
}
@override
_ImageFilter
_toNativeImageFilter
()
=>
nativeFilter
;
@override
String
get
_shortDescription
=>
'blur(
$sigmaX
,
$sigmaY
)'
;
@override
String
toString
()
=>
'ImageFilter.blur(
$sigmaX
,
$sigmaY
)'
;
@override
bool
operator
==(
Object
other
)
{
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
return
other
is
_GaussianBlurImageFilter
&&
other
.
sigmaX
==
sigmaX
&&
other
.
sigmaY
==
sigmaY
;
}
}
@override
@override
int
get
hashCode
=>
hashValues
(
_filterQuality
,
hashList
(
_data
),
_type
);
int
get
hashCode
=>
hashValues
(
sigmaX
,
sigmaY
);
}
class
_ComposeImageFilter
implements
ImageFilter
{
_ComposeImageFilter
({
required
this
.
innerFilter
,
required
this
.
outerFilter
});
final
ImageFilter
innerFilter
;
final
ImageFilter
outerFilter
;
// SkImageFilters::Compose
late
final
_ImageFilter
nativeFilter
=
_ImageFilter
.
composed
(
this
);
@override
@override
String
toString
()
{
_ImageFilter
_toNativeImageFilter
()
=>
nativeFilter
;
switch
(
_type
)
{
case
_kTypeBlur:
@override
return
'ImageFilter.blur(
${_data[0]}
,
${_data[1]}
)'
;
String
get
_shortDescription
=>
'
${innerFilter._shortDescription}
->
${outerFilter._shortDescription}
'
;
case
_kTypeMatrix:
return
'ImageFilter.matrix(
$_data
,
$_filterQuality
)'
;
@override
default
:
String
toString
()
=>
'ImageFilter.compose(source ->
$_shortDescription
-> result)'
;
return
'Unknown ImageFilter type. This is an error. If you
\'
re seeing this, please file an issue at https://github.com/flutter/flutter/issues/new.'
;
}
@override
bool
operator
==(
Object
other
)
{
if
(
other
.
runtimeType
!=
runtimeType
)
return
false
;
return
other
is
_ComposeImageFilter
&&
other
.
innerFilter
==
innerFilter
&&
other
.
outerFilter
==
outerFilter
;
}
}
@override
int
get
hashCode
=>
hashValues
(
innerFilter
,
outerFilter
);
}
}
/// An [ImageFilter] that is backed by a native SkImageFilter.
/// An [ImageFilter] that is backed by a native SkImageFilter.
...
@@ -3198,11 +3274,11 @@ class _ImageFilter extends NativeFieldWrapperClass2 {
...
@@ -3198,11 +3274,11 @@ class _ImageFilter extends NativeFieldWrapperClass2 {
void
_constructor
()
native
'ImageFilter_constructor'
;
void
_constructor
()
native
'ImageFilter_constructor'
;
/// Creates an image filter that applies a Gaussian blur.
/// Creates an image filter that applies a Gaussian blur.
_ImageFilter
.
blur
(
this
.
creato
r
)
_ImageFilter
.
blur
(
_GaussianBlurImageFilter
filte
r
)
:
assert
(
creato
r
!=
null
),
// ignore: unnecessary_null_comparison
:
assert
(
filte
r
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
creator
.
_type
==
ImageFilter
.
_kTypeBlur
)
{
creator
=
filter
{
// ignore: prefer_initializing_formals
_constructor
();
_constructor
();
_initBlur
(
creator
.
_data
[
0
],
creator
.
_data
[
1
]
);
_initBlur
(
filter
.
sigmaX
,
filter
.
sigmaY
);
}
}
void
_initBlur
(
double
sigmaX
,
double
sigmaY
)
native
'ImageFilter_initBlur'
;
void
_initBlur
(
double
sigmaX
,
double
sigmaY
)
native
'ImageFilter_initBlur'
;
...
@@ -3210,16 +3286,36 @@ class _ImageFilter extends NativeFieldWrapperClass2 {
...
@@ -3210,16 +3286,36 @@ class _ImageFilter extends NativeFieldWrapperClass2 {
///
///
/// For example, applying a positive scale matrix (see [Matrix4.diagonal3])
/// For example, applying a positive scale matrix (see [Matrix4.diagonal3])
/// when used with [BackdropFilter] would magnify the background image.
/// when used with [BackdropFilter] would magnify the background image.
_ImageFilter
.
matrix
(
this
.
creato
r
)
_ImageFilter
.
matrix
(
_MatrixImageFilter
filte
r
)
:
assert
(
creato
r
!=
null
),
// ignore: unnecessary_null_comparison
:
assert
(
filte
r
!=
null
),
// ignore: unnecessary_null_comparison
assert
(
creator
.
_type
==
ImageFilter
.
_kTypeMatrix
)
{
creator
=
filter
{
// ignore: prefer_initializing_formals
if
(
creator
.
_
data
.
length
!=
16
)
if
(
filter
.
data
.
length
!=
16
)
throw
ArgumentError
(
'"matrix4" must have 16 entries.'
);
throw
ArgumentError
(
'"matrix4" must have 16 entries.'
);
_constructor
();
_constructor
();
_initMatrix
(
creator
.
_data
,
creator
.
_filterQuality
!
.
index
);
_initMatrix
(
filter
.
data
,
filter
.
filterQuality
.
index
);
}
}
void
_initMatrix
(
Float64List
matrix4
,
int
filterQuality
)
native
'ImageFilter_initMatrix'
;
void
_initMatrix
(
Float64List
matrix4
,
int
filterQuality
)
native
'ImageFilter_initMatrix'
;
/// Converts a color filter to an image filter.
_ImageFilter
.
fromColorFilter
(
ColorFilter
filter
)
:
assert
(
filter
!=
null
),
// ignore: unnecessary_null_comparison
creator
=
filter
{
// ignore: prefer_initializing_formals
_constructor
();
final
_ColorFilter
?
nativeFilter
=
filter
.
_toNativeColorFilter
();
_initColorFilter
(
nativeFilter
);
}
void
_initColorFilter
(
_ColorFilter
?
colorFilter
)
native
'ImageFilter_initColorFilter'
;
/// Composes `_innerFilter` with `_outerFilter`.
_ImageFilter
.
composed
(
_ComposeImageFilter
filter
)
:
assert
(
filter
!=
null
),
// ignore: unnecessary_null_comparison
creator
=
filter
{
// ignore: prefer_initializing_formals
_constructor
();
final
_ImageFilter
nativeFilterInner
=
filter
.
innerFilter
.
_toNativeImageFilter
();
final
_ImageFilter
nativeFilterOuter
=
filter
.
outerFilter
.
_toNativeImageFilter
();
_initComposed
(
nativeFilterOuter
,
nativeFilterInner
);
}
void
_initComposed
(
_ImageFilter
outerFilter
,
_ImageFilter
innerFilter
)
native
'ImageFilter_initComposeFilter'
;
/// The original Dart object that created the native wrapper, which retains
/// The original Dart object that created the native wrapper, which retains
/// the values used for the filter.
/// the values used for the filter.
final
ImageFilter
creator
;
final
ImageFilter
creator
;
...
...
lib/ui/painting/image_filter.cc
浏览文件 @
e872177c
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
#include "flutter/lib/ui/painting/matrix.h"
#include "flutter/lib/ui/painting/matrix.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
#include "third_party/skia/include/effects/SkBlurImageFilter.h"
#include "third_party/skia/include/effects/SkImageFilters.h"
#include "third_party/skia/include/effects/SkImageSource.h"
#include "third_party/skia/include/effects/SkImageSource.h"
#include "third_party/skia/include/effects/SkPictureImageFilter.h"
#include "third_party/skia/include/effects/SkPictureImageFilter.h"
#include "third_party/tonic/converter/dart_converter.h"
#include "third_party/tonic/converter/dart_converter.h"
...
@@ -22,11 +23,13 @@ static void ImageFilter_constructor(Dart_NativeArguments args) {
...
@@ -22,11 +23,13 @@ static void ImageFilter_constructor(Dart_NativeArguments args) {
IMPLEMENT_WRAPPERTYPEINFO
(
ui
,
ImageFilter
);
IMPLEMENT_WRAPPERTYPEINFO
(
ui
,
ImageFilter
);
#define FOR_EACH_BINDING(V) \
#define FOR_EACH_BINDING(V) \
V(ImageFilter, initImage) \
V(ImageFilter, initImage) \
V(ImageFilter, initPicture) \
V(ImageFilter, initPicture) \
V(ImageFilter, initBlur) \
V(ImageFilter, initBlur) \
V(ImageFilter, initMatrix)
V(ImageFilter, initMatrix) \
V(ImageFilter, initColorFilter) \
V(ImageFilter, initComposeFilter)
FOR_EACH_BINDING
(
DART_NATIVE_CALLBACK
)
FOR_EACH_BINDING
(
DART_NATIVE_CALLBACK
)
...
@@ -64,4 +67,14 @@ void ImageFilter::initMatrix(const tonic::Float64List& matrix4,
...
@@ -64,4 +67,14 @@ void ImageFilter::initMatrix(const tonic::Float64List& matrix4,
nullptr
);
nullptr
);
}
}
void
ImageFilter
::
initColorFilter
(
ColorFilter
*
colorFilter
)
{
filter_
=
SkImageFilters
::
ColorFilter
(
colorFilter
?
colorFilter
->
filter
()
:
nullptr
,
nullptr
);
}
void
ImageFilter
::
initComposeFilter
(
ImageFilter
*
outer
,
ImageFilter
*
inner
)
{
filter_
=
SkImageFilters
::
Compose
(
outer
?
outer
->
filter
()
:
nullptr
,
inner
?
inner
->
filter
()
:
nullptr
);
}
}
// namespace flutter
}
// namespace flutter
lib/ui/painting/image_filter.h
浏览文件 @
e872177c
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
#define FLUTTER_LIB_UI_PAINTING_IMAGE_FILTER_H_
#define FLUTTER_LIB_UI_PAINTING_IMAGE_FILTER_H_
#include "flutter/lib/ui/dart_wrapper.h"
#include "flutter/lib/ui/dart_wrapper.h"
#include "flutter/lib/ui/painting/color_filter.h"
#include "flutter/lib/ui/painting/image.h"
#include "flutter/lib/ui/painting/image.h"
#include "flutter/lib/ui/painting/picture.h"
#include "flutter/lib/ui/painting/picture.h"
#include "third_party/skia/include/core/SkImageFilter.h"
#include "third_party/skia/include/core/SkImageFilter.h"
...
@@ -25,6 +26,8 @@ class ImageFilter : public RefCountedDartWrappable<ImageFilter> {
...
@@ -25,6 +26,8 @@ class ImageFilter : public RefCountedDartWrappable<ImageFilter> {
void
initPicture
(
Picture
*
);
void
initPicture
(
Picture
*
);
void
initBlur
(
double
sigma_x
,
double
sigma_y
);
void
initBlur
(
double
sigma_x
,
double
sigma_y
);
void
initMatrix
(
const
tonic
::
Float64List
&
matrix4
,
int
filter_quality
);
void
initMatrix
(
const
tonic
::
Float64List
&
matrix4
,
int
filter_quality
);
void
initColorFilter
(
ColorFilter
*
colorFilter
);
void
initComposeFilter
(
ImageFilter
*
outer
,
ImageFilter
*
inner
);
const
sk_sp
<
SkImageFilter
>&
filter
()
const
{
return
filter_
;
}
const
sk_sp
<
SkImageFilter
>&
filter
()
const
{
return
filter_
;
}
...
...
lib/web_ui/lib/src/engine/bitmap_canvas.dart
浏览文件 @
e872177c
...
@@ -573,15 +573,10 @@ class BitmapCanvas extends EngineCanvas {
...
@@ -573,15 +573,10 @@ class BitmapCanvas extends EngineCanvas {
ui
.
Image
image
,
ui
.
Offset
p
,
SurfacePaintData
paint
)
{
ui
.
Image
image
,
ui
.
Offset
p
,
SurfacePaintData
paint
)
{
final
HtmlImage
htmlImage
=
image
as
HtmlImage
;
final
HtmlImage
htmlImage
=
image
as
HtmlImage
;
final
ui
.
BlendMode
?
blendMode
=
paint
.
blendMode
;
final
ui
.
BlendMode
?
blendMode
=
paint
.
blendMode
;
final
EngineColorFilter
?
colorFilter
=
final
EngineColorFilter
?
colorFilter
=
paint
.
colorFilter
as
EngineColorFilter
?;
paint
.
colorFilter
as
EngineColorFilter
?;
final
ui
.
BlendMode
?
colorFilterBlendMode
=
colorFilter
?.
_blendMode
;
html
.
HtmlElement
imgElement
;
html
.
HtmlElement
imgElement
;
if
(
colorFilterBlendMode
==
null
)
{
if
(
colorFilter
is
_CkBlendModeColorFilter
)
{
// No Blending, create an image by cloning original loaded image.
switch
(
colorFilter
.
blendMode
)
{
imgElement
=
_reuseOrCreateImage
(
htmlImage
);
}
else
{
switch
(
colorFilterBlendMode
)
{
case
ui
.
BlendMode
.
colorBurn
:
case
ui
.
BlendMode
.
colorBurn
:
case
ui
.
BlendMode
.
colorDodge
:
case
ui
.
BlendMode
.
colorDodge
:
case
ui
.
BlendMode
.
hue
:
case
ui
.
BlendMode
.
hue
:
...
@@ -595,14 +590,17 @@ class BitmapCanvas extends EngineCanvas {
...
@@ -595,14 +590,17 @@ class BitmapCanvas extends EngineCanvas {
case
ui
.
BlendMode
.
color
:
case
ui
.
BlendMode
.
color
:
case
ui
.
BlendMode
.
luminosity
:
case
ui
.
BlendMode
.
luminosity
:
case
ui
.
BlendMode
.
xor
:
case
ui
.
BlendMode
.
xor
:
imgElement
=
_createImageElementWithSvgFilter
(
imgElement
=
_createImageElementWithSvgFilter
(
image
,
image
,
colorFilter
!.
_color
,
colorFilterB
lendMode
,
paint
);
colorFilter
.
color
,
colorFilter
.
b
lendMode
,
paint
);
break
;
break
;
default
:
default
:
imgElement
=
_createBackgroundImageWithBlend
(
imgElement
=
_createBackgroundImageWithBlend
(
image
,
image
,
colorFilter
!.
_color
,
colorFilterB
lendMode
,
paint
);
colorFilter
.
color
,
colorFilter
.
b
lendMode
,
paint
);
break
;
break
;
}
}
}
else
{
// No Blending, create an image by cloning original loaded image.
imgElement
=
_reuseOrCreateImage
(
htmlImage
);
}
}
imgElement
.
style
.
mixBlendMode
=
_stringForBlendMode
(
blendMode
)
??
''
;
imgElement
.
style
.
mixBlendMode
=
_stringForBlendMode
(
blendMode
)
??
''
;
if
(
_canvasPool
.
isClipped
)
{
if
(
_canvasPool
.
isClipped
)
{
...
...
lib/web_ui/lib/src/engine/canvaskit/canvas.dart
浏览文件 @
e872177c
...
@@ -241,11 +241,11 @@ class CkCanvas {
...
@@ -241,11 +241,11 @@ class CkCanvas {
}
}
void
saveLayerWithFilter
(
ui
.
Rect
bounds
,
ui
.
ImageFilter
filter
)
{
void
saveLayerWithFilter
(
ui
.
Rect
bounds
,
ui
.
ImageFilter
filter
)
{
final
CkImageFilter
skImageFilter
=
filter
as
CkImageFilter
;
final
_CkManagedSkImageFilterConvertible
convertible
=
filter
as
_CkManagedSkImageFilterConvertible
;
return
skCanvas
.
saveLayer
(
return
skCanvas
.
saveLayer
(
null
,
null
,
toSkRect
(
bounds
),
toSkRect
(
bounds
),
skI
mageFilter
.
skiaObject
,
convertible
.
_i
mageFilter
.
skiaObject
,
0
,
0
,
);
);
}
}
...
...
lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart
浏览文件 @
e872177c
...
@@ -823,6 +823,16 @@ class SkImageFilterNamespace {
...
@@ -823,6 +823,16 @@ class SkImageFilterNamespace {
SkFilterQuality
filterQuality
,
SkFilterQuality
filterQuality
,
Null
input
,
// we don't use this yet
Null
input
,
// we don't use this yet
);
);
external
SkImageFilter
MakeColorFilter
(
SkColorFilter
colorFilter
,
Null
input
,
// we don't use this yet
);
external
SkImageFilter
MakeCompose
(
SkImageFilter
outer
,
SkImageFilter
inner
,
);
}
}
@JS
()
@JS
()
...
...
lib/web_ui/lib/src/engine/canvaskit/color_filter.dart
浏览文件 @
e872177c
...
@@ -5,62 +5,147 @@
...
@@ -5,62 +5,147 @@
// @dart = 2.10
// @dart = 2.10
part of
engine
;
part of
engine
;
/// A [ui.ColorFilter] backed by Skia's [CkColorFilter].
/// A concrete [ManagedSkiaObject] subclass that owns a [SkColorFilter] and
class
CkColorFilter
extends
ManagedSkiaObject
<
SkColorFilter
>
{
/// manages its lifecycle.
final
EngineColorFilter
_engineFilter
;
///
/// Seealso:
CkColorFilter
.
mode
(
EngineColorFilter
filter
)
:
_engineFilter
=
filter
;
///
/// * [CkPaint.colorFilter], which uses a [_ManagedSkColorFilter] to manage
CkColorFilter
.
matrix
(
EngineColorFilter
filter
)
:
_engineFilter
=
filter
;
/// the lifecycle of its [SkColorFilter].
class
_ManagedSkColorFilter
extends
ManagedSkiaObject
<
SkColorFilter
>
{
CkColorFilter
.
linearToSrgbGamma
(
EngineColorFilter
filter
)
_ManagedSkColorFilter
(
CkColorFilter
ckColorFilter
)
:
_engineFilter
=
filter
;
:
this
.
ckColorFilter
=
ckColorFilter
;
CkColorFilter
.
srgbToLinearGamma
(
EngineColorFilter
filter
)
final
CkColorFilter
ckColorFilter
;
:
_engineFilter
=
filter
;
@override
SkColorFilter
_createSkiaObjectFromFilter
()
{
SkColorFilter
createDefault
()
=>
ckColorFilter
.
_initRawColorFilter
();
SkColorFilter
skColorFilter
;
switch
(
_engineFilter
.
_type
)
{
@override
case
EngineColorFilter
.
_TypeMode
:
SkColorFilter
resurrect
()
=>
ckColorFilter
.
_initRawColorFilter
();
skColorFilter
=
canvasKit
.
SkColorFilter
.
MakeBlend
(
toSharedSkColor1
(
_engineFilter
.
_color
!),
@override
toSkBlendMode
(
_engineFilter
.
_blendMode
!),
void
delete
()
{
);
rawSkiaObject
?.
delete
();
break
;
case
EngineColorFilter
.
_TypeMatrix
:
final
Float32List
colorMatrix
=
Float32List
(
20
);
final
List
<
double
>
matrix
=
_engineFilter
.
_matrix
!;
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
colorMatrix
[
i
]
=
matrix
[
i
];
}
skColorFilter
=
canvasKit
.
SkColorFilter
.
MakeMatrix
(
colorMatrix
);
break
;
case
EngineColorFilter
.
_TypeLinearToSrgbGamma
:
skColorFilter
=
canvasKit
.
SkColorFilter
.
MakeLinearToSRGBGamma
();
break
;
case
EngineColorFilter
.
_TypeSrgbToLinearGamma
:
skColorFilter
=
canvasKit
.
SkColorFilter
.
MakeSRGBToLinearGamma
();
break
;
default
:
throw
StateError
(
'Unknown mode
${_engineFilter._type}
for ColorFilter.'
);
}
return
skColorFilter
;
}
}
@override
@override
SkColorFilter
createDefault
()
{
int
get
hashCode
=>
ckColorFilter
.
hashCode
;
return
_createSkiaObjectFromFilter
();
@override
bool
operator
==(
Object
other
)
{
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
return
other
is
_ManagedSkColorFilter
&&
other
.
ckColorFilter
==
ckColorFilter
;
}
}
@override
@override
SkColorFilter
resurrect
()
{
String
toString
()
=>
ckColorFilter
.
toString
();
return
_createSkiaObjectFromFilter
();
}
/// A [ui.ColorFilter] backed by Skia's [SkColorFilter].
///
/// Additionally, this class provides the interface for converting itself to a
/// [ManagedSkiaObject] that manages a skia image filter.
abstract
class
CkColorFilter
implements
_CkManagedSkImageFilterConvertible
<
SkImageFilter
>,
EngineColorFilter
{
const
CkColorFilter
();
/// Called by [ManagedSkiaObject.createDefault] and
/// [ManagedSkiaObject.resurrect] to create a new [SKImageFilter], when this
/// filter is used as an [ImageFilter].
SkImageFilter
_initRawImageFilter
()
=>
canvasKit
.
SkImageFilter
.
MakeColorFilter
(
_initRawColorFilter
(),
null
);
/// Called by [ManagedSkiaObject.createDefault] and
/// [ManagedSkiaObject.resurrect] to create a new [SKColorFilter], when this
/// filter is used as a [ColorFilter].
SkColorFilter
_initRawColorFilter
();
ManagedSkiaObject
<
SkImageFilter
>
get
_imageFilter
=>
_CkColorFilterImageFilter
(
colorFilter:
this
);
}
class
_CkBlendModeColorFilter
extends
CkColorFilter
{
const
_CkBlendModeColorFilter
(
this
.
color
,
this
.
blendMode
);
final
ui
.
Color
color
;
final
ui
.
BlendMode
blendMode
;
@override
SkColorFilter
_initRawColorFilter
()
{
return
canvasKit
.
SkColorFilter
.
MakeBlend
(
toSharedSkColor1
(
color
),
toSkBlendMode
(
blendMode
),
);
}
}
@override
@override
void
delete
()
{
int
get
hashCode
=>
ui
.
hashValues
(
color
,
blendMode
);
rawSkiaObject
?.
delete
();
@override
bool
operator
==(
Object
other
)
{
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
return
other
is
_CkBlendModeColorFilter
&&
other
.
color
==
color
&&
other
.
blendMode
==
blendMode
;
}
@override
String
toString
()
=>
'ColorFilter.mode(
$color
,
$blendMode
)'
;
}
class
_CkMatrixColorFilter
extends
CkColorFilter
{
const
_CkMatrixColorFilter
(
this
.
matrix
);
final
List
<
double
>
matrix
;
@override
SkColorFilter
_initRawColorFilter
()
{
assert
(
this
.
matrix
.
length
==
20
,
'Color Matrix must have 20 entries.'
);
final
List
<
double
>
matrix
=
this
.
matrix
;
if
(
matrix
is
Float32List
)
return
canvasKit
.
SkColorFilter
.
MakeMatrix
(
matrix
);
final
Float32List
float32Matrix
=
Float32List
(
20
);
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
float32Matrix
[
i
]
=
matrix
[
i
];
}
return
canvasKit
.
SkColorFilter
.
MakeMatrix
(
float32Matrix
);
}
}
@override
int
get
hashCode
=>
ui
.
hashList
(
matrix
);
@override
bool
operator
==(
Object
other
)
{
return
runtimeType
==
other
.
runtimeType
&&
other
is
_CkMatrixColorFilter
&&
_listEquals
<
double
>(
matrix
,
other
.
matrix
);
}
@override
String
toString
()
=>
'ColorFilter.matrix(
$matrix
)'
;
}
class
_CkLinearToSrgbGammaColorFilter
extends
CkColorFilter
{
const
_CkLinearToSrgbGammaColorFilter
();
@override
SkColorFilter
_initRawColorFilter
()
=>
canvasKit
.
SkColorFilter
.
MakeLinearToSRGBGamma
();
@override
bool
operator
==(
Object
other
)
=>
runtimeType
==
other
.
runtimeType
;
@override
String
toString
()
=>
'ColorFilter.linearToSrgbGamma()'
;
}
class
_CkSrgbToLinearGammaColorFilter
extends
CkColorFilter
{
const
_CkSrgbToLinearGammaColorFilter
();
@override
SkColorFilter
_initRawColorFilter
()
=>
canvasKit
.
SkColorFilter
.
MakeSRGBToLinearGamma
();
@override
bool
operator
==(
Object
other
)
=>
runtimeType
==
other
.
runtimeType
;
@override
String
toString
()
=>
'ColorFilter.srgbToLinearGamma()'
;
}
}
lib/web_ui/lib/src/engine/canvaskit/image_filter.dart
浏览文件 @
e872177c
...
@@ -5,16 +5,30 @@
...
@@ -5,16 +5,30 @@
// @dart = 2.10
// @dart = 2.10
part of
engine
;
part of
engine
;
/// An [ImageFilter] that can create a managed skia [SkImageFilter] object.
///
/// Concrete subclasses of this interface must provide efficient implementation
/// of [operator==], to avoid re-creating the underlying skia filters
/// whenever possible.
///
/// Currently implemented by [CkImageFilter] and [CkColorFilter].
abstract
class
_CkManagedSkImageFilterConvertible
<
T
extends
Object
>
implements
ui
.
ImageFilter
{
ManagedSkiaObject
<
SkImageFilter
>
get
_imageFilter
;
}
/// The CanvasKit implementation of [ui.ImageFilter].
/// The CanvasKit implementation of [ui.ImageFilter].
///
///
/// Currently only supports `blur`.
/// Currently only supports `blur`.
class
CkImageFilter
extends
ManagedSkiaObject
<
SkImageFilter
>
implements
ui
.
ImageFilter
{
abstract
class
CkImageFilter
extends
ManagedSkiaObject
<
SkImageFilter
>
implements
_CkManagedSkImageFilterConvertible
<
SkImageFilter
>
{
CkImageFilter
.
blur
({
double
sigmaX
=
0.0
,
double
sigmaY
=
0.0
})
factory
CkImageFilter
.
blur
({
required
double
sigmaX
,
required
double
sigmaY
})
=
_CkBlurImageFilter
;
:
_sigmaX
=
sigmaX
,
factory
CkImageFilter
.
color
({
required
CkColorFilter
colorFilter
})
=
_CkColorFilterImageFilter
;
_sigmaY
=
sigmaY
;
CkImageFilter
.
_
();
@override
ManagedSkiaObject
<
SkImageFilter
>
get
_imageFilter
=>
this
;
final
double
_sigmaX
;
SkImageFilter
_initSkiaObject
();
final
double
_sigmaY
;
@override
@override
SkImageFilter
createDefault
()
=>
_initSkiaObject
();
SkImageFilter
createDefault
()
=>
_initSkiaObject
();
...
@@ -26,11 +40,42 @@ class CkImageFilter extends ManagedSkiaObject<SkImageFilter> implements ui.Image
...
@@ -26,11 +40,42 @@ class CkImageFilter extends ManagedSkiaObject<SkImageFilter> implements ui.Image
void
delete
()
{
void
delete
()
{
rawSkiaObject
?.
delete
();
rawSkiaObject
?.
delete
();
}
}
}
class
_CkColorFilterImageFilter
extends
CkImageFilter
{
_CkColorFilterImageFilter
({
required
this
.
colorFilter
})
:
super
.
_
();
final
CkColorFilter
colorFilter
;
@override
SkImageFilter
_initSkiaObject
()
=>
colorFilter
.
_initRawImageFilter
();
@override
int
get
hashCode
=>
colorFilter
.
hashCode
;
@override
bool
operator
==(
Object
other
)
{
if
(
runtimeType
!=
other
.
runtimeType
)
return
false
;
return
other
is
_CkColorFilterImageFilter
&&
other
.
colorFilter
==
colorFilter
;
}
@override
String
toString
()
=>
colorFilter
.
toString
();
}
class
_CkBlurImageFilter
extends
CkImageFilter
{
_CkBlurImageFilter
({
required
this
.
sigmaX
,
required
this
.
sigmaY
})
:
super
.
_
();
final
double
sigmaX
;
final
double
sigmaY
;
@override
SkImageFilter
_initSkiaObject
()
{
SkImageFilter
_initSkiaObject
()
{
return
canvasKit
.
SkImageFilter
.
MakeBlur
(
return
canvasKit
.
SkImageFilter
.
MakeBlur
(
_
sigmaX
,
sigmaX
,
_
sigmaY
,
sigmaY
,
canvasKit
.
TileMode
.
Clamp
,
canvasKit
.
TileMode
.
Clamp
,
null
,
null
,
);
);
...
@@ -38,16 +83,19 @@ class CkImageFilter extends ManagedSkiaObject<SkImageFilter> implements ui.Image
...
@@ -38,16 +83,19 @@ class CkImageFilter extends ManagedSkiaObject<SkImageFilter> implements ui.Image
@override
@override
bool
operator
==(
Object
other
)
{
bool
operator
==(
Object
other
)
{
return
other
is
CkImageFilter
if
(
runtimeType
!=
other
.
runtimeType
)
&&
other
.
_sigmaX
==
_sigmaX
return
false
;
&&
other
.
_sigmaY
==
_sigmaY
;
return
other
is
_CkBlurImageFilter
&&
other
.
sigmaX
==
sigmaX
&&
other
.
sigmaY
==
sigmaY
;
}
}
@override
@override
int
get
hashCode
=>
ui
.
hashValues
(
_sigmaX
,
_
sigmaY
);
int
get
hashCode
=>
ui
.
hashValues
(
sigmaX
,
sigmaY
);
@override
@override
String
toString
()
{
String
toString
()
{
return
'ImageFilter.blur(
$
_sigmaX
,
$_
sigmaY
)'
;
return
'ImageFilter.blur(
$
sigmaX
,
$
sigmaY
)'
;
}
}
}
}
lib/web_ui/lib/src/engine/canvaskit/painting.dart
浏览文件 @
e872177c
...
@@ -165,20 +165,22 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
...
@@ -165,20 +165,22 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
ui
.
FilterQuality
_filterQuality
=
ui
.
FilterQuality
.
none
;
ui
.
FilterQuality
_filterQuality
=
ui
.
FilterQuality
.
none
;
@override
@override
ui
.
ColorFilter
?
get
colorFilter
=>
_
c
olorFilter
;
ui
.
ColorFilter
?
get
colorFilter
=>
_
managedColorFilter
?.
ckC
olorFilter
;
@override
@override
set
colorFilter
(
ui
.
ColorFilter
?
value
)
{
set
colorFilter
(
ui
.
ColorFilter
?
value
)
{
if
(
_
colorFilter
==
value
)
{
if
(
colorFilter
==
value
)
{
return
;
return
;
}
}
final
EngineColorFilter
?
engineValue
=
value
as
EngineColorFilter
?;
_colorFilter
=
engineValue
;
if
(
value
==
null
)
{
_ckColorFilter
=
engineValue
?.
_toCkColorFilter
();
_managedColorFilter
=
null
;
skiaObject
.
setColorFilter
(
_ckColorFilter
?.
skiaObject
);
}
else
{
_managedColorFilter
=
_ManagedSkColorFilter
(
value
as
CkColorFilter
);
}
skiaObject
.
setColorFilter
(
_managedColorFilter
?.
skiaObject
);
}
}
EngineColorFilter
?
_colorFilter
;
_ManagedSkColorFilter
?
_managedColorFilter
;
CkColorFilter
?
_ckColorFilter
;
@override
@override
double
get
strokeMiterLimit
=>
_strokeMiterLimit
;
double
get
strokeMiterLimit
=>
_strokeMiterLimit
;
...
@@ -200,11 +202,14 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
...
@@ -200,11 +202,14 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
if
(
_imageFilter
==
value
)
{
if
(
_imageFilter
==
value
)
{
return
;
return
;
}
}
_imageFilter
=
value
as
CkImageFilter
?;
skiaObject
.
setImageFilter
(
_imageFilter
?.
skiaObject
);
_imageFilter
=
value
as
_CkManagedSkImageFilterConvertible
?;
_managedImageFilter
=
_imageFilter
?.
_imageFilter
;
skiaObject
.
setImageFilter
(
_managedImageFilter
?.
skiaObject
);
}
}
CkImageFilter
?
_imageFilter
;
_CkManagedSkImageFilterConvertible
?
_imageFilter
;
ManagedSkiaObject
<
SkImageFilter
>?
_managedImageFilter
;
@override
@override
SkPaint
createDefault
()
{
SkPaint
createDefault
()
{
...
@@ -224,8 +229,8 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
...
@@ -224,8 +229,8 @@ class CkPaint extends ManagedSkiaObject<SkPaint> implements ui.Paint {
paint
.
setColorInt
(
_color
.
value
);
paint
.
setColorInt
(
_color
.
value
);
paint
.
setShader
(
_shader
?.
skiaObject
);
paint
.
setShader
(
_shader
?.
skiaObject
);
paint
.
setMaskFilter
(
_ckMaskFilter
?.
skiaObject
);
paint
.
setMaskFilter
(
_ckMaskFilter
?.
skiaObject
);
paint
.
setColorFilter
(
_
ck
ColorFilter
?.
skiaObject
);
paint
.
setColorFilter
(
_
managed
ColorFilter
?.
skiaObject
);
paint
.
setImageFilter
(
_
i
mageFilter
?.
skiaObject
);
paint
.
setImageFilter
(
_
managedI
mageFilter
?.
skiaObject
);
paint
.
setFilterQuality
(
toSkFilterQuality
(
_filterQuality
));
paint
.
setFilterQuality
(
toSkFilterQuality
(
_filterQuality
));
paint
.
setStrokeCap
(
toSkStrokeCap
(
_strokeCap
));
paint
.
setStrokeCap
(
toSkStrokeCap
(
_strokeCap
));
paint
.
setStrokeJoin
(
toSkStrokeJoin
(
_strokeJoin
));
paint
.
setStrokeJoin
(
toSkStrokeJoin
(
_strokeJoin
));
...
...
lib/web_ui/lib/src/engine/color_filter.dart
浏览文件 @
e872177c
...
@@ -21,11 +21,7 @@ class EngineColorFilter implements ui.ColorFilter {
...
@@ -21,11 +21,7 @@ class EngineColorFilter implements ui.ColorFilter {
/// The output of this filter is then composited into the background according
/// The output of this filter is then composited into the background according
/// to the [Paint.blendMode], using the output of this filter as the source
/// to the [Paint.blendMode], using the output of this filter as the source
/// and the background as the destination.
/// and the background as the destination.
const
EngineColorFilter
.
mode
(
ui
.
Color
color
,
ui
.
BlendMode
blendMode
)
const
factory
EngineColorFilter
.
mode
(
ui
.
Color
color
,
ui
.
BlendMode
blendMode
)
=
_CkBlendModeColorFilter
;
:
_color
=
color
,
_blendMode
=
blendMode
,
_matrix
=
null
,
_type
=
_TypeMode
;
/// Construct a color filter that transforms a color by a 5x5 matrix, where
/// Construct a color filter that transforms a color by a 5x5 matrix, where
/// the fifth row is implicitly added in an identity configuration.
/// the fifth row is implicitly added in an identity configuration.
...
@@ -87,86 +83,13 @@ class EngineColorFilter implements ui.ColorFilter {
...
@@ -87,86 +83,13 @@ class EngineColorFilter implements ui.ColorFilter {
/// 0, 0, 0, 1, 0,
/// 0, 0, 0, 1, 0,
/// ]);
/// ]);
/// ```
/// ```
const
EngineColorFilter
.
matrix
(
List
<
double
>
matrix
)
const
factory
EngineColorFilter
.
matrix
(
List
<
double
>
matrix
)
=
_CkMatrixColorFilter
;
:
_color
=
null
,
_blendMode
=
null
,
_matrix
=
matrix
,
_type
=
_TypeMatrix
;
/// Construct a color filter that applies the sRGB gamma curve to the RGB
/// Construct a color filter that applies the sRGB gamma curve to the RGB
/// channels.
/// channels.
const
EngineColorFilter
.
linearToSrgbGamma
()
const
factory
EngineColorFilter
.
linearToSrgbGamma
()
=
_CkLinearToSrgbGammaColorFilter
;
:
_color
=
null
,
_blendMode
=
null
,
_matrix
=
null
,
_type
=
_TypeLinearToSrgbGamma
;
/// Creates a color filter that applies the inverse of the sRGB gamma curve
/// Creates a color filter that applies the inverse of the sRGB gamma curve
/// to the RGB channels.
/// to the RGB channels.
const
EngineColorFilter
.
srgbToLinearGamma
()
const
factory
EngineColorFilter
.
srgbToLinearGamma
()
=
_CkSrgbToLinearGammaColorFilter
;
:
_color
=
null
,
_blendMode
=
null
,
_matrix
=
null
,
_type
=
_TypeSrgbToLinearGamma
;
final
ui
.
Color
?
_color
;
final
ui
.
BlendMode
?
_blendMode
;
final
List
<
double
>?
_matrix
;
final
int
_type
;
// The type of CkColorFilter class to create for Skia.
static
const
int
_TypeMode
=
1
;
// MakeModeFilter
static
const
int
_TypeMatrix
=
2
;
// MakeMatrixFilterRowMajor255
static
const
int
_TypeLinearToSrgbGamma
=
3
;
// MakeLinearToSRGBGamma
static
const
int
_TypeSrgbToLinearGamma
=
4
;
// MakeSRGBToLinearGamma
@override
bool
operator
==(
Object
other
)
{
return
other
is
EngineColorFilter
&&
other
.
_type
==
_type
&&
_listEquals
<
double
>(
other
.
_matrix
,
_matrix
)
&&
other
.
_color
==
_color
&&
other
.
_blendMode
==
_blendMode
;
}
CkColorFilter
?
_toCkColorFilter
()
{
switch
(
_type
)
{
case
_TypeMode:
if
(
_color
==
null
||
_blendMode
==
null
)
{
return
null
;
}
return
CkColorFilter
.
mode
(
this
);
case
_TypeMatrix:
if
(
_matrix
==
null
)
{
return
null
;
}
assert
(
_matrix
!.
length
==
20
,
'Color Matrix must have 20 entries.'
);
return
CkColorFilter
.
matrix
(
this
);
case
_TypeLinearToSrgbGamma:
return
CkColorFilter
.
linearToSrgbGamma
(
this
);
case
_TypeSrgbToLinearGamma:
return
CkColorFilter
.
srgbToLinearGamma
(
this
);
default
:
throw
StateError
(
'Unknown mode
$_type
for ColorFilter.'
);
}
}
@override
int
get
hashCode
=>
ui
.
hashValues
(
_color
,
_blendMode
,
ui
.
hashList
(
_matrix
),
_type
);
@override
String
toString
()
{
switch
(
_type
)
{
case
_TypeMode:
return
'ColorFilter.mode(
$_color
,
$_blendMode
)'
;
case
_TypeMatrix:
return
'ColorFilter.matrix(
$_matrix
)'
;
case
_TypeLinearToSrgbGamma:
return
'ColorFilter.linearToSrgbGamma()'
;
case
_TypeSrgbToLinearGamma:
return
'ColorFilter.srgbToLinearGamma()'
;
default
:
return
'Unknown ColorFilter type. This is an error. If you
\'
re seeing this, please file an issue at https://github.com/flutter/flutter/issues/new.'
;
}
}
}
}
lib/web_ui/lib/src/engine/html/color_filter.dart
浏览文件 @
e872177c
...
@@ -60,74 +60,71 @@ class PersistedColorFilter extends PersistedContainerSurface
...
@@ -60,74 +60,71 @@ class PersistedColorFilter extends PersistedContainerSurface
childContainer
?.
style
.
visibility
=
'visible'
;
childContainer
?.
style
.
visibility
=
'visible'
;
return
;
return
;
}
}
if
(
engineValue
.
_blendMode
==
null
)
{
rootElement
!.
style
.
backgroundColor
=
if
(
engineValue
is
!
_CkBlendModeColorFilter
)
{
colorToCssString
(
engineValue
.
_color
!);
childContainer
?.
style
.
visibility
=
'visible'
;
childContainer
?.
style
.
visibility
=
'visible'
;
return
;
return
;
}
}
ui
.
Color
filterColor
=
engineValue
.
_color
!
;
ui
.
Color
filterColor
=
engineValue
.
color
;
ui
.
BlendMode
?
colorFilterBlendMode
=
engineValue
.
_
blendMode
;
ui
.
BlendMode
colorFilterBlendMode
=
engineValue
.
blendMode
;
html
.
CssStyleDeclaration
style
=
rootElement
!.
style
;
html
.
CssStyleDeclaration
style
=
rootElement
!.
style
;
if
(
colorFilterBlendMode
!=
null
)
{
switch
(
colorFilterBlendMode
)
{
switch
(
colorFilterBlendMode
)
{
case
ui
.
BlendMode
.
clear
:
case
ui
.
BlendMode
.
clear
:
case
ui
.
BlendMode
.
dstOut
:
case
ui
.
BlendMode
.
dstOut
:
case
ui
.
BlendMode
.
srcOut
:
case
ui
.
BlendMode
.
srcOut
:
childContainer
?.
style
.
visibility
=
'hidden'
;
childContainer
?.
style
.
visibility
=
'hidden'
;
return
;
return
;
case
ui
.
BlendMode
.
dst
:
case
ui
.
BlendMode
.
dst
:
case
ui
.
BlendMode
.
dstIn
:
case
ui
.
BlendMode
.
dstIn
:
// Noop.
// Noop.
return
;
case
ui
.
BlendMode
.
src
:
case
ui
.
BlendMode
.
srcOver
:
// Uses source filter color.
// Since we don't have a size, we can't use background color.
// Use svg filter srcIn instead.
colorFilterBlendMode
=
ui
.
BlendMode
.
srcIn
;
break
;
case
ui
.
BlendMode
.
dstOver
:
case
ui
.
BlendMode
.
srcIn
:
case
ui
.
BlendMode
.
srcATop
:
case
ui
.
BlendMode
.
dstATop
:
case
ui
.
BlendMode
.
xor
:
case
ui
.
BlendMode
.
plus
:
case
ui
.
BlendMode
.
modulate
:
case
ui
.
BlendMode
.
screen
:
case
ui
.
BlendMode
.
overlay
:
case
ui
.
BlendMode
.
darken
:
case
ui
.
BlendMode
.
lighten
:
case
ui
.
BlendMode
.
colorDodge
:
case
ui
.
BlendMode
.
colorBurn
:
case
ui
.
BlendMode
.
hardLight
:
case
ui
.
BlendMode
.
softLight
:
case
ui
.
BlendMode
.
difference
:
case
ui
.
BlendMode
.
exclusion
:
case
ui
.
BlendMode
.
multiply
:
case
ui
.
BlendMode
.
hue
:
case
ui
.
BlendMode
.
saturation
:
case
ui
.
BlendMode
.
color
:
case
ui
.
BlendMode
.
luminosity
:
break
;
}
// Use SVG filter for blend mode.
String
?
svgFilter
=
svgFilterFromBlendMode
(
filterColor
,
colorFilterBlendMode
);
if
(
svgFilter
!=
null
)
{
_filterElement
=
html
.
Element
.
html
(
svgFilter
,
treeSanitizer:
_NullTreeSanitizer
());
rootElement
!.
append
(
_filterElement
!);
rootElement
!.
style
.
filter
=
'url(#_fcf
${_filterIdCounter}
)'
;
if
(
colorFilterBlendMode
==
ui
.
BlendMode
.
saturation
||
colorFilterBlendMode
==
ui
.
BlendMode
.
multiply
||
colorFilterBlendMode
==
ui
.
BlendMode
.
modulate
)
{
style
.
backgroundColor
=
colorToCssString
(
filterColor
);
}
return
;
return
;
case
ui
.
BlendMode
.
src
:
case
ui
.
BlendMode
.
srcOver
:
// Uses source filter color.
// Since we don't have a size, we can't use background color.
// Use svg filter srcIn instead.
colorFilterBlendMode
=
ui
.
BlendMode
.
srcIn
;
break
;
case
ui
.
BlendMode
.
dstOver
:
case
ui
.
BlendMode
.
srcIn
:
case
ui
.
BlendMode
.
srcATop
:
case
ui
.
BlendMode
.
dstATop
:
case
ui
.
BlendMode
.
xor
:
case
ui
.
BlendMode
.
plus
:
case
ui
.
BlendMode
.
modulate
:
case
ui
.
BlendMode
.
screen
:
case
ui
.
BlendMode
.
overlay
:
case
ui
.
BlendMode
.
darken
:
case
ui
.
BlendMode
.
lighten
:
case
ui
.
BlendMode
.
colorDodge
:
case
ui
.
BlendMode
.
colorBurn
:
case
ui
.
BlendMode
.
hardLight
:
case
ui
.
BlendMode
.
softLight
:
case
ui
.
BlendMode
.
difference
:
case
ui
.
BlendMode
.
exclusion
:
case
ui
.
BlendMode
.
multiply
:
case
ui
.
BlendMode
.
hue
:
case
ui
.
BlendMode
.
saturation
:
case
ui
.
BlendMode
.
color
:
case
ui
.
BlendMode
.
luminosity
:
break
;
}
// Use SVG filter for blend mode.
String
?
svgFilter
=
svgFilterFromBlendMode
(
filterColor
,
colorFilterBlendMode
);
if
(
svgFilter
!=
null
)
{
_filterElement
=
html
.
Element
.
html
(
svgFilter
,
treeSanitizer:
_NullTreeSanitizer
());
rootElement
!.
append
(
_filterElement
!);
rootElement
!.
style
.
filter
=
'url(#_fcf
${_filterIdCounter}
)'
;
if
(
colorFilterBlendMode
==
ui
.
BlendMode
.
saturation
||
colorFilterBlendMode
==
ui
.
BlendMode
.
multiply
||
colorFilterBlendMode
==
ui
.
BlendMode
.
modulate
)
{
style
.
backgroundColor
=
colorToCssString
(
filterColor
);
}
}
return
;
}
}
}
}
...
...
lib/web_ui/lib/src/ui/painting.dart
浏览文件 @
e872177c
...
@@ -406,6 +406,12 @@ class ImageFilter {
...
@@ -406,6 +406,12 @@ class ImageFilter {
// if (matrix4.length != 16)
// if (matrix4.length != 16)
// throw ArgumentError('"matrix4" must have 16 entries.');
// throw ArgumentError('"matrix4" must have 16 entries.');
}
}
ImageFilter
.
compose
({
required
ImageFilter
outer
,
required
ImageFilter
inner
})
{
// TODO(flutter_web): add implementation.
throw
UnimplementedError
(
'ImageFilter.compose not implemented for web platform.'
);
}
}
}
enum
ImageByteFormat
{
enum
ImageByteFormat
{
...
...
lib/web_ui/test/canvaskit/canvaskit_api_test.dart
浏览文件 @
e872177c
...
@@ -474,6 +474,26 @@ void _imageFilterTests() {
...
@@ -474,6 +474,26 @@ void _imageFilterTests() {
isNotNull
,
isNotNull
,
);
);
});
});
test
(
'MakeColorFilter'
,
()
{
expect
(
canvasKit
.
SkImageFilter
.
MakeColorFilter
(
canvasKit
.
SkColorFilter
.
MakeLinearToSRGBGamma
(),
null
,
),
isNotNull
,
);
});
test
(
'MakeCompose'
,
()
{
expect
(
canvasKit
.
SkImageFilter
.
MakeCompose
(
canvasKit
.
SkImageFilter
.
MakeBlur
(
1
,
2
,
canvasKit
.
TileMode
.
Repeat
,
null
),
canvasKit
.
SkImageFilter
.
MakeBlur
(
1
,
2
,
canvasKit
.
TileMode
.
Repeat
,
null
),
),
isNotNull
,
);
});
}
}
void
_mallocTests
(
)
{
void
_mallocTests
(
)
{
...
...
lib/web_ui/test/canvaskit/filter_test.dart
0 → 100644
浏览文件 @
e872177c
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.6
import
'dart:typed_data'
;
import
'package:test/bootstrap/browser.dart'
;
import
'package:test/test.dart'
;
import
'package:ui/src/engine.dart'
;
import
'package:ui/ui.dart'
as
ui
;
import
'common.dart'
;
void
main
(
)
{
internalBootstrapBrowserTest
(()
=>
testMain
);
}
void
testMain
(
)
{
List
<
CkColorFilter
>
createColorFilters
()
{
return
<
CkColorFilter
>[
EngineColorFilter
.
mode
(
ui
.
Color
(
0x12345678
),
ui
.
BlendMode
.
srcOver
)
as
CkColorFilter
,
EngineColorFilter
.
mode
(
ui
.
Color
(
0x12345678
),
ui
.
BlendMode
.
dstOver
)
as
CkColorFilter
,
EngineColorFilter
.
mode
(
ui
.
Color
(
0x87654321
),
ui
.
BlendMode
.
dstOver
)
as
CkColorFilter
,
EngineColorFilter
.
matrix
(<
double
>[
1
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
])
as
CkColorFilter
,
EngineColorFilter
.
matrix
(
Float32List
.
fromList
(<
double
>[
2
,
0
,
0
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
0
,
2
,
0
,
]))
as
CkColorFilter
,
EngineColorFilter
.
linearToSrgbGamma
()
as
CkColorFilter
,
EngineColorFilter
.
srgbToLinearGamma
()
as
CkColorFilter
,
];
}
List
<
CkImageFilter
>
createImageFilters
()
{
return
<
CkImageFilter
>[
CkImageFilter
.
blur
(
sigmaX:
5
,
sigmaY:
6
),
CkImageFilter
.
blur
(
sigmaX:
6
,
sigmaY:
5
),
for
(
final
CkColorFilter
colorFilter
in
createColorFilters
())
CkImageFilter
.
color
(
colorFilter:
colorFilter
),
];
}
group
(
'ImageFilters'
,
()
{
setUpAll
(()
async
{
await
ui
.
webOnlyInitializePlatform
();
});
test
(
'can be constructed'
,
()
{
final
CkImageFilter
imageFilter
=
CkImageFilter
.
blur
(
sigmaX:
5
,
sigmaY:
10
);
expect
(
imageFilter
,
isA
<
CkImageFilter
>());
expect
(
imageFilter
.
createDefault
(),
isNotNull
);
expect
(
imageFilter
.
resurrect
(),
isNotNull
);
});
test
(
'== operator'
,
()
{
final
List
<
ui
.
ImageFilter
>
filters1
=
<
ui
.
ImageFilter
>[
...
createImageFilters
(),
...
createColorFilters
(),
];
final
List
<
ui
.
ImageFilter
>
filters2
=
<
ui
.
ImageFilter
>[
...
createImageFilters
(),
...
createColorFilters
(),
];
for
(
int
index1
=
0
;
index1
<
filters1
.
length
;
index1
+=
1
)
{
final
ui
.
ImageFilter
imageFilter1
=
filters1
[
index1
];
expect
(
imageFilter1
==
imageFilter1
,
isTrue
);
for
(
int
index2
=
0
;
index2
<
filters2
.
length
;
index2
+=
1
)
{
final
ui
.
ImageFilter
imageFilter2
=
filters2
[
index2
];
expect
(
imageFilter1
==
imageFilter2
,
imageFilter2
==
imageFilter1
);
expect
(
imageFilter1
==
imageFilter2
,
index1
==
index2
);
}
}
});
test
(
'reuses the Skia filter'
,
()
{
final
CkPaint
paint
=
CkPaint
();
paint
.
imageFilter
=
CkImageFilter
.
blur
(
sigmaX:
5
,
sigmaY:
10
);
final
ManagedSkiaObject
managedFilter
=
paint
.
imageFilter
as
ManagedSkiaObject
;
final
Object
skiaFilter
=
managedFilter
?.
skiaObject
;
paint
.
imageFilter
=
CkImageFilter
.
blur
(
sigmaX:
5
,
sigmaY:
10
);
expect
((
paint
.
imageFilter
as
ManagedSkiaObject
).
skiaObject
,
same
(
skiaFilter
));
});
// TODO: https://github.com/flutter/flutter/issues/60040
},
skip:
isIosSafari
);
}
testing/dart/image_filter_test.dart
浏览文件 @
e872177c
...
@@ -8,6 +8,7 @@ import 'dart:ui';
...
@@ -8,6 +8,7 @@ import 'dart:ui';
import
'package:test/test.dart'
;
import
'package:test/test.dart'
;
const
Color
red
=
Color
(
0xFFAA0000
);
const
Color
green
=
Color
(
0xFF00AA00
);
const
Color
green
=
Color
(
0xFF00AA00
);
const
int
greenCenterBlurred
=
0x1C001300
;
const
int
greenCenterBlurred
=
0x1C001300
;
...
@@ -18,6 +19,34 @@ const int greenCenterScaled = 0xFF00AA00;
...
@@ -18,6 +19,34 @@ const int greenCenterScaled = 0xFF00AA00;
const
int
greenSideScaled
=
0x80005500
;
const
int
greenSideScaled
=
0x80005500
;
const
int
greenCornerScaled
=
0x40002B00
;
const
int
greenCornerScaled
=
0x40002B00
;
const
List
<
double
>
grayscaleColorMatrix
=
<
double
>[
0.2126
,
0.7152
,
0.0722
,
0
,
0
,
0.2126
,
0.7152
,
0.0722
,
0
,
0
,
0.2126
,
0.7152
,
0.0722
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
];
const
List
<
double
>
identityColorMatrix
=
<
double
>[
1
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
];
const
List
<
double
>
constValueColorMatrix
=
<
double
>[
0
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
2
,
0
,
0
,
0
,
0
,
255
,
];
const
List
<
double
>
halvesBrightnessColorMatrix
=
<
double
>[
0.5
,
0
,
0
,
0
,
0
,
0
,
0.5
,
0
,
0
,
0
,
0
,
0
,
0.5
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
];
void
main
(
)
{
void
main
(
)
{
Future
<
Uint32List
>
getBytesForPaint
(
Paint
paint
,
{
int
width
=
3
,
int
height
=
3
})
async
{
Future
<
Uint32List
>
getBytesForPaint
(
Paint
paint
,
{
int
width
=
3
,
int
height
=
3
})
async
{
final
PictureRecorder
recorder
=
PictureRecorder
();
final
PictureRecorder
recorder
=
PictureRecorder
();
...
@@ -31,6 +60,18 @@ void main() {
...
@@ -31,6 +60,18 @@ void main() {
return
bytes
.
buffer
.
asUint32List
();
return
bytes
.
buffer
.
asUint32List
();
}
}
Future
<
Uint32List
>
getBytesForColorPaint
(
Paint
paint
,
{
int
width
=
1
,
int
height
=
1
})
async
{
final
PictureRecorder
recorder
=
PictureRecorder
();
final
Canvas
recorderCanvas
=
Canvas
(
recorder
);
recorderCanvas
.
drawPaint
(
paint
);
final
Picture
picture
=
recorder
.
endRecording
();
final
Image
image
=
await
picture
.
toImage
(
width
,
height
);
final
ByteData
bytes
=
await
image
.
toByteData
();
expect
(
bytes
.
lengthInBytes
,
width
*
height
*
4
);
return
bytes
.
buffer
.
asUint32List
();
}
ImageFilter
makeBlur
(
double
sigmaX
,
double
sigmaY
)
=>
ImageFilter
makeBlur
(
double
sigmaX
,
double
sigmaY
)
=>
ImageFilter
.
blur
(
sigmaX:
sigmaX
,
sigmaY:
sigmaY
);
ImageFilter
.
blur
(
sigmaX:
sigmaX
,
sigmaY:
sigmaY
);
...
@@ -47,6 +88,20 @@ void main() {
...
@@ -47,6 +88,20 @@ void main() {
]),
filterQuality:
quality
);
]),
filterQuality:
quality
);
}
}
List
<
ColorFilter
>
colorFilters
()
{
// Create new color filter instances on each invocation.
return
<
ColorFilter
>
[
// ignore: prefer_const_constructors
ColorFilter
.
mode
(
null
,
null
),
// ignore: prefer_const_constructors
ColorFilter
.
mode
(
green
,
BlendMode
.
color
),
// ignore: prefer_const_constructors
ColorFilter
.
mode
(
red
,
BlendMode
.
color
),
// ignore: prefer_const_constructors
ColorFilter
.
mode
(
red
,
BlendMode
.
screen
),
// ignore: prefer_const_constructors
ColorFilter
.
matrix
(
null
),
// ignore: prefer_const_constructors
ColorFilter
.
matrix
(
grayscaleColorMatrix
),
// ignore: prefer_const_constructors
ColorFilter
.
linearToSrgbGamma
(),
// ignore: prefer_const_constructors
ColorFilter
.
srgbToLinearGamma
(),
// ignore: prefer_const_constructors
];
}
List
<
ImageFilter
>
makeList
()
{
List
<
ImageFilter
>
makeList
()
{
return
<
ImageFilter
>[
return
<
ImageFilter
>[
makeBlur
(
10.0
,
10.0
),
makeBlur
(
10.0
,
10.0
),
...
@@ -59,6 +114,7 @@ void main() {
...
@@ -59,6 +114,7 @@ void main() {
makeScale
(
10.0
,
10.0
,
0.0
,
0.0
,
FilterQuality
.
medium
),
makeScale
(
10.0
,
10.0
,
0.0
,
0.0
,
FilterQuality
.
medium
),
makeScale
(
10.0
,
10.0
,
0.0
,
0.0
,
FilterQuality
.
high
),
makeScale
(
10.0
,
10.0
,
0.0
,
0.0
,
FilterQuality
.
high
),
makeScale
(
10.0
,
10.0
,
0.0
,
0.0
,
FilterQuality
.
none
),
makeScale
(
10.0
,
10.0
,
0.0
,
0.0
,
FilterQuality
.
none
),
...
colorFilters
(),
];
];
}
}
...
@@ -78,12 +134,19 @@ void main() {
...
@@ -78,12 +134,19 @@ void main() {
}
}
}
}
List
<
ImageFilter
>
composed
(
List
<
ImageFilter
>
a
,
List
<
ImageFilter
>
b
)
{
return
<
ImageFilter
>[
for
(
final
ImageFilter
x
in
a
)
for
(
final
ImageFilter
y
in
b
)
ImageFilter
.
compose
(
outer:
x
,
inner:
y
)];
}
test
(
'ImageFilter - equals'
,
()
async
{
test
(
'ImageFilter - equals'
,
()
async
{
final
List
<
ImageFilter
>
A
=
makeList
();
final
List
<
ImageFilter
>
A
=
makeList
();
final
List
<
ImageFilter
>
B
=
makeList
();
final
List
<
ImageFilter
>
B
=
makeList
();
checkEquality
(
A
,
A
);
checkEquality
(
A
,
A
);
checkEquality
(
A
,
B
);
checkEquality
(
A
,
B
);
checkEquality
(
B
,
B
);
checkEquality
(
B
,
B
);
checkEquality
(
composed
(
A
,
A
),
composed
(
A
,
A
));
checkEquality
(
composed
(
A
,
B
),
composed
(
B
,
A
));
checkEquality
(
composed
(
B
,
B
),
composed
(
B
,
B
));
});
});
void
checkBytes
(
Uint32List
bytes
,
int
center
,
int
side
,
int
corner
)
{
void
checkBytes
(
Uint32List
bytes
,
int
center
,
int
side
,
int
corner
)
{
...
@@ -117,4 +180,117 @@ void main() {
...
@@ -117,4 +180,117 @@ void main() {
final
Uint32List
bytes
=
await
getBytesForPaint
(
paint
);
final
Uint32List
bytes
=
await
getBytesForPaint
(
paint
);
checkBytes
(
bytes
,
greenCenterScaled
,
greenSideScaled
,
greenCornerScaled
);
checkBytes
(
bytes
,
greenCenterScaled
,
greenSideScaled
,
greenCornerScaled
);
});
});
test
(
'ImageFilter - matrix: copies the list'
,
()
async
{
final
Float64List
matrix
=
Float64List
.
fromList
(<
double
>[
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
0.0
,
0.0
,
0.0
,
0.0
,
1.0
,
]);
final
ImageFilter
filter
=
ImageFilter
.
matrix
(
matrix
);
final
String
originalDescription
=
filter
.
toString
();
// Modify the matrix.
matrix
[
0
]
=
12345
;
expect
(
filter
.
toString
(),
contains
(
'[1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0]'
));
expect
(
filter
.
toString
(),
originalDescription
);
});
test
(
'ImageFilter - null color filters do not throw'
,
()
{
dynamic
error
;
final
Paint
paint
=
Paint
();
try
{
paint
..
color
=
green
..
imageFilter
=
const
ColorFilter
.
mode
(
null
,
null
);
}
catch
(
e
)
{
error
=
e
;
}
expect
(
error
,
isNull
);
});
test
(
'ImageFilter - from color filters'
,
()
async
{
final
Paint
paint
=
Paint
()
..
color
=
green
..
imageFilter
=
const
ColorFilter
.
matrix
(
constValueColorMatrix
);
final
Uint32List
bytes
=
await
getBytesForColorPaint
(
paint
);
expect
(
bytes
[
0
],
0xFF020202
);
});
test
(
'ImageFilter - null filter composition'
,
()
async
{
const
ImageFilter
nullFilter
=
ColorFilter
.
mode
(
null
,
null
);
const
ImageFilter
identityFilter
=
ColorFilter
.
matrix
(
identityColorMatrix
);
// Verify that null filter == identity.
Future
<
void
>
verifyAgainst
(
ImageFilter
filter
)
async
{
final
ImageFilter
comp0
=
ImageFilter
.
compose
(
outer:
filter
,
inner:
identityFilter
);
final
ImageFilter
comp1
=
ImageFilter
.
compose
(
outer:
filter
,
inner:
nullFilter
);
final
ImageFilter
comp2
=
ImageFilter
.
compose
(
outer:
nullFilter
,
inner:
filter
);
final
Paint
paint
=
Paint
()..
color
=
green
;
paint
.
imageFilter
=
comp0
;
final
Uint32List
bytes
=
await
getBytesForColorPaint
(
paint
);
paint
.
imageFilter
=
comp1
;
expect
(
bytes
,
equals
(
await
getBytesForColorPaint
(
paint
)));
paint
.
imageFilter
=
comp2
;
expect
(
bytes
,
equals
(
await
getBytesForColorPaint
(
paint
)));
}
makeList
().
forEach
(
verifyAgainst
);
});
test
(
'ImageFilter - color filter composition'
,
()
async
{
final
ImageFilter
compOrder1
=
ImageFilter
.
compose
(
outer:
const
ColorFilter
.
matrix
(
halvesBrightnessColorMatrix
),
inner:
const
ColorFilter
.
matrix
(
constValueColorMatrix
),
);
final
ImageFilter
compOrder2
=
ImageFilter
.
compose
(
outer:
const
ColorFilter
.
matrix
(
constValueColorMatrix
),
inner:
const
ColorFilter
.
matrix
(
halvesBrightnessColorMatrix
),
);
final
Paint
paint
=
Paint
()
..
color
=
green
..
imageFilter
=
compOrder1
;
Uint32List
bytes
=
await
getBytesForColorPaint
(
paint
);
expect
(
bytes
[
0
],
0xFF010101
);
paint
..
color
=
green
..
imageFilter
=
compOrder2
;
bytes
=
await
getBytesForColorPaint
(
paint
);
expect
(
bytes
[
0
],
0xFF020202
);
});
test
(
'Composite ImageFilter toString'
,
()
{
expect
(
ImageFilter
.
compose
(
outer:
makeBlur
(
20.0
,
20.0
),
inner:
makeBlur
(
10.0
,
10.0
)).
toString
(),
contains
(
'blur(10.0, 10.0) -> blur(20.0, 20.0)'
),
);
// Produces a flat list of filters
expect
(
ImageFilter
.
compose
(
outer:
ImageFilter
.
compose
(
outer:
makeBlur
(
30.0
,
30.0
),
inner:
makeBlur
(
20.0
,
20.0
)),
inner:
ImageFilter
.
compose
(
outer:
const
ColorFilter
.
mode
(
null
,
null
),
inner:
makeScale
(
10.0
,
10.0
),
),
).
toString
(),
contains
(
'matrix([10.0, 0.0, 0.0, 0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, -0.0, -0.0, 0.0, 1.0], FilterQuality.low) -> '
'ColorFilter.mode(null, null) -> '
'blur(20.0, 20.0) -> '
'blur(30.0, 30.0)'
),
);
});
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录