Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
41a92052
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
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,发现更多精彩内容 >>
未验证
提交
41a92052
编写于
4月 27, 2021
作者:
F
Ferhat
提交者:
GitHub
4月 27, 2021
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Implement ColorFilter.matrix for html renderer (#25769)
上级
1019008f
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
126 addition
and
37 deletion
+126
-37
lib/web_ui/dev/goldens_lock.yaml
lib/web_ui/dev/goldens_lock.yaml
+1
-1
lib/web_ui/lib/src/engine/bitmap_canvas.dart
lib/web_ui/lib/src/engine/bitmap_canvas.dart
+47
-24
lib/web_ui/lib/src/engine/html/color_filter.dart
lib/web_ui/lib/src/engine/html/color_filter.dart
+36
-6
lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart
...ui/test/golden_tests/engine/canvas_image_filter_test.dart
+22
-6
lib/web_ui/test/golden_tests/engine/color_filter_golden_test.dart
...ui/test/golden_tests/engine/color_filter_golden_test.dart
+20
-0
未找到文件。
lib/web_ui/dev/goldens_lock.yaml
浏览文件 @
41a92052
repository
:
https://github.com/flutter/goldens.git
repository
:
https://github.com/flutter/goldens.git
revision
:
8d866a84b7ceb67412ce6767ea0c1eec2eb3fa3f
revision
:
4a8da9f65353bda26a73e12838797f20cfdedc40
lib/web_ui/lib/src/engine/bitmap_canvas.dart
浏览文件 @
41a92052
...
@@ -631,29 +631,11 @@ class BitmapCanvas extends EngineCanvas {
...
@@ -631,29 +631,11 @@ class BitmapCanvas extends EngineCanvas {
paint
.
colorFilter
as
EngineColorFilter
?;
paint
.
colorFilter
as
EngineColorFilter
?;
html
.
HtmlElement
imgElement
;
html
.
HtmlElement
imgElement
;
if
(
colorFilter
is
_CkBlendModeColorFilter
)
{
if
(
colorFilter
is
_CkBlendModeColorFilter
)
{
switch
(
colorFilter
.
blendMode
)
{
imgElement
=
_createImageElementWithBlend
(
image
,
case
ui
.
BlendMode
.
colorBurn
:
colorFilter
.
color
,
colorFilter
.
blendMode
,
paint
);
case
ui
.
BlendMode
.
colorDodge
:
}
else
if
(
colorFilter
is
_CkMatrixColorFilter
)
{
case
ui
.
BlendMode
.
hue
:
imgElement
=
_createImageElementWithSvgColorMatrixFilter
(
case
ui
.
BlendMode
.
modulate
:
image
,
colorFilter
.
matrix
,
paint
);
case
ui
.
BlendMode
.
overlay
:
case
ui
.
BlendMode
.
plus
:
case
ui
.
BlendMode
.
srcIn
:
case
ui
.
BlendMode
.
srcATop
:
case
ui
.
BlendMode
.
srcOut
:
case
ui
.
BlendMode
.
saturation
:
case
ui
.
BlendMode
.
color
:
case
ui
.
BlendMode
.
luminosity
:
case
ui
.
BlendMode
.
xor
:
case
ui
.
BlendMode
.
dstATop
:
imgElement
=
_createImageElementWithSvgFilter
(
image
,
colorFilter
.
color
,
colorFilter
.
blendMode
,
paint
);
break
;
default
:
imgElement
=
_createBackgroundImageWithBlend
(
image
,
colorFilter
.
color
,
colorFilter
.
blendMode
,
paint
);
break
;
}
}
else
{
}
else
{
// No Blending, create an image by cloning original loaded image.
// No Blending, create an image by cloning original loaded image.
imgElement
=
_reuseOrCreateImage
(
htmlImage
);
imgElement
=
_reuseOrCreateImage
(
htmlImage
);
...
@@ -683,6 +665,31 @@ class BitmapCanvas extends EngineCanvas {
...
@@ -683,6 +665,31 @@ class BitmapCanvas extends EngineCanvas {
return
imgElement
;
return
imgElement
;
}
}
html
.
HtmlElement
_createImageElementWithBlend
(
HtmlImage
image
,
ui
.
Color
color
,
ui
.
BlendMode
blendMode
,
SurfacePaintData
paint
)
{
switch
(
blendMode
)
{
case
ui
.
BlendMode
.
colorBurn
:
case
ui
.
BlendMode
.
colorDodge
:
case
ui
.
BlendMode
.
hue
:
case
ui
.
BlendMode
.
modulate
:
case
ui
.
BlendMode
.
overlay
:
case
ui
.
BlendMode
.
plus
:
case
ui
.
BlendMode
.
srcIn
:
case
ui
.
BlendMode
.
srcATop
:
case
ui
.
BlendMode
.
srcOut
:
case
ui
.
BlendMode
.
saturation
:
case
ui
.
BlendMode
.
color
:
case
ui
.
BlendMode
.
luminosity
:
case
ui
.
BlendMode
.
xor
:
case
ui
.
BlendMode
.
dstATop
:
return
_createImageElementWithSvgBlendFilter
(
image
,
color
,
blendMode
,
paint
);
default
:
return
_createBackgroundImageWithBlend
(
image
,
color
,
blendMode
,
paint
);
}
}
@override
@override
void
drawImageRect
(
void
drawImageRect
(
ui
.
Image
image
,
ui
.
Rect
src
,
ui
.
Rect
dst
,
SurfacePaintData
paint
)
{
ui
.
Image
image
,
ui
.
Rect
src
,
ui
.
Rect
dst
,
SurfacePaintData
paint
)
{
...
@@ -811,7 +818,7 @@ class BitmapCanvas extends EngineCanvas {
...
@@ -811,7 +818,7 @@ class BitmapCanvas extends EngineCanvas {
}
}
// Creates an image element and an svg filter to apply on the element.
// Creates an image element and an svg filter to apply on the element.
html
.
HtmlElement
_createImageElementWithSvgFilter
(
html
.
HtmlElement
_createImageElementWithSvg
Blend
Filter
(
HtmlImage
image
,
HtmlImage
image
,
ui
.
Color
?
filterColor
,
ui
.
Color
?
filterColor
,
ui
.
BlendMode
colorFilterBlendMode
,
ui
.
BlendMode
colorFilterBlendMode
,
...
@@ -831,6 +838,22 @@ class BitmapCanvas extends EngineCanvas {
...
@@ -831,6 +838,22 @@ class BitmapCanvas extends EngineCanvas {
return
imgElement
;
return
imgElement
;
}
}
// Creates an image element and an svg color matrix filter to apply on the element.
html
.
HtmlElement
_createImageElementWithSvgColorMatrixFilter
(
HtmlImage
image
,
List
<
double
>
matrix
,
SurfacePaintData
paint
)
{
// For srcIn blendMode, we use an svg filter to apply to image element.
String
?
svgFilter
=
svgFilterFromColorMatrix
(
matrix
);
final
html
.
Element
filterElement
=
html
.
Element
.
html
(
svgFilter
,
treeSanitizer:
_NullTreeSanitizer
());
rootElement
.
append
(
filterElement
);
_children
.
add
(
filterElement
);
final
html
.
HtmlElement
imgElement
=
_reuseOrCreateImage
(
image
);
imgElement
.
style
.
filter
=
'url(#_fcf
${_filterIdCounter}
)'
;
return
imgElement
;
}
// Should be called when we add new html elements into rootElement so that
// Should be called when we add new html elements into rootElement so that
// paint order is preserved.
// paint order is preserved.
//
//
...
...
lib/web_ui/lib/src/engine/html/color_filter.dart
浏览文件 @
41a92052
...
@@ -59,14 +59,18 @@ class PersistedColorFilter extends PersistedContainerSurface
...
@@ -59,14 +59,18 @@ class PersistedColorFilter extends PersistedContainerSurface
childContainer
?.
style
.
visibility
=
'visible'
;
childContainer
?.
style
.
visibility
=
'visible'
;
return
;
return
;
}
}
if
(
engineValue
is
_CkBlendModeColorFilter
)
{
if
(
engineValue
is
!
_CkBlendModeColorFilter
)
{
_applyBlendModeFilter
(
engineValue
);
}
else
if
(
engineValue
is
_CkMatrixColorFilter
)
{
_applyMatrixColorFilter
(
engineValue
);
}
else
{
childContainer
?.
style
.
visibility
=
'visible'
;
childContainer
?.
style
.
visibility
=
'visible'
;
return
;
}
}
}
ui
.
Color
filterColor
=
engineValue
.
color
;
void
_applyBlendModeFilter
(
_CkBlendModeColorFilter
colorFilter
)
{
ui
.
BlendMode
colorFilterBlendMode
=
engineValue
.
blendMode
;
ui
.
Color
filterColor
=
colorFilter
.
color
;
ui
.
BlendMode
colorFilterBlendMode
=
colorFilter
.
blendMode
;
html
.
CssStyleDeclaration
style
=
rootElement
!.
style
;
html
.
CssStyleDeclaration
style
=
rootElement
!.
style
;
switch
(
colorFilterBlendMode
)
{
switch
(
colorFilterBlendMode
)
{
case
ui
.
BlendMode
.
clear
:
case
ui
.
BlendMode
.
clear
:
...
@@ -123,7 +127,16 @@ class PersistedColorFilter extends PersistedContainerSurface
...
@@ -123,7 +127,16 @@ class PersistedColorFilter extends PersistedContainerSurface
colorFilterBlendMode
==
ui
.
BlendMode
.
modulate
)
{
colorFilterBlendMode
==
ui
.
BlendMode
.
modulate
)
{
style
.
backgroundColor
=
colorToCssString
(
filterColor
);
style
.
backgroundColor
=
colorToCssString
(
filterColor
);
}
}
return
;
}
}
void
_applyMatrixColorFilter
(
_CkMatrixColorFilter
colorFilter
)
{
String
?
svgFilter
=
svgFilterFromColorMatrix
(
colorFilter
.
matrix
);
if
(
svgFilter
!=
null
)
{
_filterElement
=
html
.
Element
.
html
(
svgFilter
,
treeSanitizer:
_NullTreeSanitizer
());
rootElement
!.
append
(
_filterElement
!);
rootElement
!.
style
.
filter
=
'url(#_fcf
${_filterIdCounter}
)'
;
}
}
}
}
...
@@ -215,6 +228,23 @@ String? svgFilterFromBlendMode(
...
@@ -215,6 +228,23 @@ String? svgFilterFromBlendMode(
return
svgFilter
;
return
svgFilter
;
}
}
String
?
svgFilterFromColorMatrix
(
List
<
double
>
matrix
)
{
_filterIdCounter
+=
1
;
final
StringBuffer
sbMatrix
=
StringBuffer
();
assert
(
matrix
.
length
==
20
);
for
(
int
i
=
0
;
i
<
20
;
i
++)
{
if
(
i
!=
0
)
{
sbMatrix
.
write
(
' '
);
}
sbMatrix
.
write
(
matrix
[
i
]);
}
return
'
$kSvgResourceHeader
'
'<filter id="_fcf
$_filterIdCounter
" '
'filterUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">'
'<feColorMatrix values="
$sbMatrix
" result="comp"/>'
'</filter></svg>'
;
}
int
_filterIdCounter
=
0
;
int
_filterIdCounter
=
0
;
// The color matrix for feColorMatrix element changes colors based on
// The color matrix for feColorMatrix element changes colors based on
...
...
lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart
浏览文件 @
41a92052
...
@@ -24,11 +24,27 @@ void testMain() async {
...
@@ -24,11 +24,27 @@ void testMain() async {
// Regression test for https://github.com/flutter/flutter/issues/76966
// Regression test for https://github.com/flutter/flutter/issues/76966
test
(
'Draws image with dstATop color filter'
,
()
async
{
test
(
'Draws image with dstATop color filter'
,
()
async
{
final
RecordingCanvas
canvas
=
RecordingCanvas
(
region
);
final
RecordingCanvas
canvas
=
RecordingCanvas
(
region
);
canvas
.
drawImage
(
createFlutterLogoTestImage
(),
Offset
(
10
,
10
),
canvas
.
drawImage
(
makePaint
()
createFlutterLogoTestImage
(),
..
colorFilter
=
EngineColorFilter
.
mode
(
Color
(
0x40000000
),
Offset
(
10
,
10
),
BlendMode
.
dstATop
));
makePaint
()
await
canvasScreenshot
(
canvas
,
'image_color_fiter_dstatop'
,
..
colorFilter
=
region:
region
);
EngineColorFilter
.
mode
(
Color
(
0x40000000
),
BlendMode
.
dstATop
));
await
canvasScreenshot
(
canvas
,
'image_color_fiter_dstatop'
,
region:
region
);
});
test
(
'Draws image with matrix color filter'
,
()
async
{
final
RecordingCanvas
canvas
=
RecordingCanvas
(
region
);
canvas
.
drawImage
(
createFlutterLogoTestImage
(),
Offset
(
10
,
10
),
makePaint
()
..
colorFilter
=
EngineColorFilter
.
matrix
(<
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
,
//
]));
await
canvasScreenshot
(
canvas
,
'image_matrix_color_fiter'
,
region:
region
);
});
});
}
}
lib/web_ui/test/golden_tests/engine/color_filter_golden_test.dart
浏览文件 @
41a92052
...
@@ -48,6 +48,26 @@ void testMain() async {
...
@@ -48,6 +48,26 @@ void testMain() async {
maxDiffRatePercent:
12.0
);
maxDiffRatePercent:
12.0
);
});
});
test
(
'Should apply matrix color filter to image'
,
()
async
{
final
List
<
double
>
colorMatrix
=
<
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
,
//
];
final
SurfaceSceneBuilder
builder
=
SurfaceSceneBuilder
();
final
Picture
backgroundPicture
=
_drawBackground
();
builder
.
addPicture
(
Offset
.
zero
,
backgroundPicture
);
builder
.
pushColorFilter
(
EngineColorFilter
.
matrix
(
colorMatrix
));
final
Picture
circles1
=
_drawTestPictureWithCircles
(
30
,
30
);
builder
.
addPicture
(
Offset
.
zero
,
circles1
);
builder
.
pop
();
html
.
document
.
body
!.
append
(
builder
.
build
().
webOnlyRootElement
!);
await
matchGoldenFile
(
'color_filter_matrix.png'
,
region:
region
,
maxDiffRatePercent:
12.0
);
});
/// Regression test for https://github.com/flutter/flutter/issues/59451.
/// Regression test for https://github.com/flutter/flutter/issues/59451.
///
///
/// Picture with overlay blend inside a physical shape. Should show image
/// Picture with overlay blend inside a physical shape. Should show image
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录