From dbdf2312042b1b37bcc49776edc169b572b720c6 Mon Sep 17 00:00:00 2001 From: ferhatb Date: Mon, 22 Mar 2021 10:59:49 -0700 Subject: [PATCH 1/5] Fix drawImage colorFilter with dstATop blend mode --- lib/web_ui/lib/src/engine/bitmap_canvas.dart | 1 + .../lib/src/engine/html/color_filter.dart | 18 ++- .../engine/canvas_image_blend_mode_test.dart | 139 ++---------------- .../engine/canvas_image_filter_test.dart | 35 +++++ .../test/golden_tests/engine/testimage.dart | 125 ++++++++++++++++ 5 files changed, 190 insertions(+), 128 deletions(-) create mode 100644 lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart create mode 100644 lib/web_ui/test/golden_tests/engine/testimage.dart diff --git a/lib/web_ui/lib/src/engine/bitmap_canvas.dart b/lib/web_ui/lib/src/engine/bitmap_canvas.dart index 13932f70dc424..66e07127b7b26 100644 --- a/lib/web_ui/lib/src/engine/bitmap_canvas.dart +++ b/lib/web_ui/lib/src/engine/bitmap_canvas.dart @@ -649,6 +649,7 @@ class BitmapCanvas extends EngineCanvas { 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; diff --git a/lib/web_ui/lib/src/engine/html/color_filter.dart b/lib/web_ui/lib/src/engine/html/color_filter.dart index 4b203897b52ac..239c631821971 100644 --- a/lib/web_ui/lib/src/engine/html/color_filter.dart +++ b/lib/web_ui/lib/src/engine/html/color_filter.dart @@ -149,6 +149,9 @@ String? svgFilterFromBlendMode( case ui.BlendMode.srcOut: svgFilter = _srcOutColorFilterToSvg(filterColor); break; + case ui.BlendMode.dstATop: + svgFilter = _dstATopColorFilterToSvg(filterColor); + break; case ui.BlendMode.xor: svgFilter = _xorColorFilterToSvg(filterColor); break; @@ -199,7 +202,6 @@ String? svgFilterFromBlendMode( break; case ui.BlendMode.src: case ui.BlendMode.dst: - case ui.BlendMode.dstATop: case ui.BlendMode.dstIn: case ui.BlendMode.dstOut: case ui.BlendMode.dstOver: @@ -246,6 +248,20 @@ String _srcInColorFilterToSvg(ui.Color? color) { ''; } +/// The destination that overlaps the source is composited with the source and +/// replaces the destination. dst-atop CR = CB*αB*αA+CA*αA*(1-αB) αR=αA +String _dstATopColorFilterToSvg(ui.Color? color) { + _filterIdCounter += 1; + return '$kSvgResourceHeader' + '' + '' + '' + '' + '' + ''; +} + String _srcOutColorFilterToSvg(ui.Color? color) { _filterIdCounter += 1; return '$kSvgResourceHeader' diff --git a/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart b/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart index c568fa199bad0..5a618b6688f87 100644 --- a/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart +++ b/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart @@ -12,6 +12,9 @@ import 'package:ui/src/engine.dart'; import 'package:web_engine_tester/golden_tester.dart'; +import 'screenshot.dart'; +import 'testimage.dart'; + void main() { internalBootstrapBrowserTest(() => testMain); } @@ -81,28 +84,28 @@ void testMain() async { rc.drawRect(Rect.fromLTWH(200, top, 200, 50), Paint() ..color = grey); BlendMode blendMode = blendModes[row]; - rc.drawImage(createTestImage(), Offset(0, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(0, top), Paint() ..colorFilter = EngineColorFilter.mode(red, blendMode)); - rc.drawImage(createTestImage(), Offset(50, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(50, top), Paint() ..colorFilter = EngineColorFilter.mode(green, blendMode)); - rc.drawImage(createTestImage(), Offset(100, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(100, top), Paint() ..colorFilter = EngineColorFilter.mode(blue, blendMode)); - rc.drawImage(createTestImage(), Offset(150, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(150, top), Paint() ..colorFilter = EngineColorFilter.mode(black, blendMode)); - rc.drawImage(createTestImage(), Offset(200, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(200, top), Paint() ..colorFilter = EngineColorFilter.mode(red, blendMode)); - rc.drawImage(createTestImage(), Offset(250, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(250, top), Paint() ..colorFilter = EngineColorFilter.mode(green, blendMode)); - rc.drawImage(createTestImage(), Offset(300, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(300, top), Paint() ..colorFilter = EngineColorFilter.mode(blue, blendMode)); - rc.drawImage(createTestImage(), Offset(350, top), + rc.drawImage(createFlutterLogoTestImage(), Offset(350, top), Paint() ..colorFilter = EngineColorFilter.mode(black, blendMode)); } @@ -121,7 +124,7 @@ void testMain() async { rc.save(); rc.drawRect(Rect.fromLTWH(0, 50, 200, 50), Paint() ..color = white); - rc.drawImage(createTestImage(), Offset(0, 50), + rc.drawImage(createFlutterLogoTestImage(), Offset(0, 50), Paint() ..colorFilter = EngineColorFilter.mode(red, BlendMode.srcIn)); @@ -148,121 +151,3 @@ Paragraph createTestParagraph() { builder.addText('FOO'); return builder.build(); } - - -// 50x50 pixel flutter logo image. -const String _flutterLogoBase64 = - 'iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAKRlWElm' - 'TU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgExAAIAAAAg' - 'AAAAWodpAAQAAAABAAAAegAAAAAAAABIAAAAAQAAAEgAAAABQWRvYmUgUGhvdG9zaG9wIENT' - 'NiAoTWFjaW50b3NoKQAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAMqADAAQAAAABAAAAMgAA' - 'AABWBXsWAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEemlUWHRYTUw6Y29tLmFkb2JlLnhtcAAA' - 'AAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENv' - 'cmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5' - 'OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjph' - 'Ym91dD0iIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94' - 'YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5j' - 'b20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0i' - 'aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0i' - 'aHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8eG1wTU06SW5zdGFu' - 'Y2VJRD54bXAuaWlkOjMyOERERjc5ODRCRjExRUE5QUE4OEM5NTZDREM5QkUyPC94bXBNTTp' - 'JbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjMyOERERj' - 'dBODRCRjExRUE5QUE4OEM5NTZDREM5QkUyPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgI' - 'CA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6MDE4MDExNzQwNzIwNjgxMTgy' - 'MkFBQjU0OEFBMDMwM0E8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHht' - 'cE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICA' - 'gPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDowNDgwMTE3NDA3MjA2ODExODIyQUFCNTQ4QU' - 'EwMzAzQTwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SU' - 'Q+eG1wLmRpZDowMTgwMTE3NDA3MjA2ODExODIyQUFCNTQ4QUEwMzAzQTwvc3RSZWY6ZG9jd' - 'W1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHhtcDpD' - 'cmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpPC94bXA6Q3JlYXRv' - 'clRvb2w+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb2' - '4+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhP' - 'gr/+ApQAAAQNUlEQVRoBbVaDYxdRRWemTv3vt2WbrctpRYxtCVU4io1LomElrjYWnbbgtr2' - 'CbISwGpR0UBUjD8YHyZCNCqIP5GmtLWSAn3SVYqw7PbnFUQFXGOMRUFlW9G2gKalu/veu38' - 'zfufce3ff275dWtBJ5s7cuTPnnO+cM2d+3pN2urDiVSHEVCFuOpgT35vVIuaLV8Tgtw8Icf' - 'PZkZgntDggrhNCbhHCuihD9J402Y4OLUulqNy1+iwvFIscaaqRMWqyQRofIxFH2ohpwqjDc' - 't/OZyyYSTAVHQUtSoVIfPiL7xWu3i2i0KA7PnFmstpaEVMLBnHm1rFHhEbiQZ9PKtl83pPF' - 'YnB0xVVne2HlKcdz5wgTC62cZLwlGdJUSxXtWnngFItIOhdzj3xeiWIxzrpPVmpAZg4EJjc' - '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'; - -HtmlImage createTestImage() { - return HtmlImage( - html.ImageElement() - ..src = 'data:text/plain;base64,$_flutterLogoBase64', - 50, - 50, - ); -} diff --git a/lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart b/lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart new file mode 100644 index 0000000000000..135d5ccc1024a --- /dev/null +++ b/lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart @@ -0,0 +1,35 @@ +// 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:html' as html; + +import 'package:test/bootstrap/browser.dart'; +import 'package:test/test.dart'; +import 'package:ui/ui.dart' hide TextStyle; +import 'package:ui/src/engine.dart'; + +import 'screenshot.dart'; +import 'testimage.dart'; + +void main() { + internalBootstrapBrowserTest(() => testMain); +} + +void testMain() async { + const double screenWidth = 100.0; + const double screenHeight = 100.0; + const Rect region = Rect.fromLTWH(0, 0, screenWidth, screenHeight); + + // Regression test for https://github.com/flutter/flutter/issues/76966 + test('Draws image with dstATop color filter', () async { + final RecordingCanvas canvas = RecordingCanvas(region); + canvas.drawImage(createFlutterLogoTestImage(), Offset(10, 10), + Paint() + ..colorFilter = EngineColorFilter.mode(Color(0x40000000), + BlendMode.dstATop)); + await canvasScreenshot(canvas, 'image_color_fiter_dstatop', + region: region, write: true); + }); +} diff --git a/lib/web_ui/test/golden_tests/engine/testimage.dart b/lib/web_ui/test/golden_tests/engine/testimage.dart new file mode 100644 index 0000000000000..c1b569063a4aa --- /dev/null +++ b/lib/web_ui/test/golden_tests/engine/testimage.dart @@ -0,0 +1,125 @@ +// 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. + +import 'dart:html' as html; + +import 'package:ui/src/engine.dart'; + +/// 50x50 pixel flutter logo image that contains alpha ramps and colors +/// specifically to transparency and blending. +const String _flutterLogoBase64 = + 'iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAKRlWElm' + 'TU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgExAAIAAAAg' + 'AAAAWodpAAQAAAABAAAAegAAAAAAAABIAAAAAQAAAEgAAAABQWRvYmUgUGhvdG9zaG9wIENT' + 'NiAoTWFjaW50b3NoKQAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAMqADAAQAAAABAAAAMgAA' + 'AABWBXsWAAAACXBIWXMAAAsTAAALEwEAmpwYAAAEemlUWHRYTUw6Y29tLmFkb2JlLnhtcAAA' + 'AAAAPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENv' + 'cmUgNS40LjAiPgogICA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5' + 'OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPgogICAgICA8cmRmOkRlc2NyaXB0aW9uIHJkZjph' + 'Ym91dD0iIgogICAgICAgICAgICB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94' + 'YXAvMS4wL21tLyIKICAgICAgICAgICAgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5j' + 'b20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiCiAgICAgICAgICAgIHhtbG5zOnhtcD0i' + 'aHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgICAgICAgICAgeG1sbnM6dGlmZj0i' + 'aHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8eG1wTU06SW5zdGFu' + 'Y2VJRD54bXAuaWlkOjMyOERERjc5ODRCRjExRUE5QUE4OEM5NTZDREM5QkUyPC94bXBNTTp' + 'JbnN0YW5jZUlEPgogICAgICAgICA8eG1wTU06RG9jdW1lbnRJRD54bXAuZGlkOjMyOERERj' + 'dBODRCRjExRUE5QUE4OEM5NTZDREM5QkUyPC94bXBNTTpEb2N1bWVudElEPgogICAgICAgI' + 'CA8eG1wTU06T3JpZ2luYWxEb2N1bWVudElEPnhtcC5kaWQ6MDE4MDExNzQwNzIwNjgxMTgy' + 'MkFBQjU0OEFBMDMwM0E8L3htcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD4KICAgICAgICAgPHht' + 'cE1NOkRlcml2ZWRGcm9tIHJkZjpwYXJzZVR5cGU9IlJlc291cmNlIj4KICAgICAgICAgICA' + 'gPHN0UmVmOmluc3RhbmNlSUQ+eG1wLmlpZDowNDgwMTE3NDA3MjA2ODExODIyQUFCNTQ4QU' + 'EwMzAzQTwvc3RSZWY6aW5zdGFuY2VJRD4KICAgICAgICAgICAgPHN0UmVmOmRvY3VtZW50SU' + 'Q+eG1wLmRpZDowMTgwMTE3NDA3MjA2ODExODIyQUFCNTQ4QUEwMzAzQTwvc3RSZWY6ZG9jd' + 'W1lbnRJRD4KICAgICAgICAgPC94bXBNTTpEZXJpdmVkRnJvbT4KICAgICAgICAgPHhtcDpD' + 'cmVhdG9yVG9vbD5BZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpPC94bXA6Q3JlYXRv' + 'clRvb2w+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb2' + '4+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhP' + 'gr/+ApQAAAQNUlEQVRoBbVaDYxdRRWemTv3vt2WbrctpRYxtCVU4io1LomElrjYWnbbgtr2' + 'CbISwGpR0UBUjD8YHyZCNCqIP5GmtLWSAn3SVYqw7PbnFUQFXGOMRUFlW9G2gKalu/veu38' + 'zfufce3ff275dWtBJ5s7cuTPnnO+cM2d+3pN2urDiVSHEVCFuOpgT35vVIuaLV8Tgtw8Icf' + 'PZkZgntDggrhNCbhHCuihD9J402Y4OLUulqNy1+iwvFIscaaqRMWqyQRofIxFH2ohpwqjDc' + 't/OZyyYSTAVHQUtSoVIfPiL7xWu3i2i0KA7PnFmstpaEVMLBnHm1rFHhEbiQZ9PKtl83pPF' + 'YnB0xVVne2HlKcdz5wgTC62cZLwlGdJUSxXtWnngFItIOhdzj3xeiWIxzrpPVmpAZg4EJjc' + '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'; + +HtmlImage createFlutterLogoTestImage() { + return HtmlImage( + html.ImageElement() + ..src = 'data:text/plain;base64,$_flutterLogoBase64', + 50, + 50, + ); +} From 488da3a98aed0561260122331022971e574649f9 Mon Sep 17 00:00:00 2001 From: ferhatb Date: Mon, 22 Mar 2021 11:30:54 -0700 Subject: [PATCH 2/5] update golden locks --- lib/web_ui/dev/goldens_lock.yaml | 2 +- .../test/golden_tests/engine/canvas_image_filter_test.dart | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/web_ui/dev/goldens_lock.yaml b/lib/web_ui/dev/goldens_lock.yaml index 67d9c9535574f..72d0359c70d78 100644 --- a/lib/web_ui/dev/goldens_lock.yaml +++ b/lib/web_ui/dev/goldens_lock.yaml @@ -1,2 +1,2 @@ repository: https://github.com/flutter/goldens.git -revision: b86dc52ac1c8725ea17c50d9a7704687b5252833 +revision: 02ca90916f341a215d44fab6a13fefa7e865c372 diff --git a/lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart b/lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart index 135d5ccc1024a..a98b6a1ed88bf 100644 --- a/lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart +++ b/lib/web_ui/test/golden_tests/engine/canvas_image_filter_test.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. // @dart = 2.6 -import 'dart:html' as html; import 'package:test/bootstrap/browser.dart'; import 'package:test/test.dart'; @@ -30,6 +29,6 @@ void testMain() async { ..colorFilter = EngineColorFilter.mode(Color(0x40000000), BlendMode.dstATop)); await canvasScreenshot(canvas, 'image_color_fiter_dstatop', - region: region, write: true); + region: region); }); } From 0c4146ac1564f5ccf293549c1eaa196032e80d40 Mon Sep 17 00:00:00 2001 From: ferhatb Date: Mon, 22 Mar 2021 11:53:40 -0700 Subject: [PATCH 3/5] remove unused import --- .../test/golden_tests/engine/canvas_image_blend_mode_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart b/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart index 5a618b6688f87..ddcb1f7e70d4b 100644 --- a/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart +++ b/lib/web_ui/test/golden_tests/engine/canvas_image_blend_mode_test.dart @@ -12,7 +12,6 @@ import 'package:ui/src/engine.dart'; import 'package:web_engine_tester/golden_tester.dart'; -import 'screenshot.dart'; import 'testimage.dart'; void main() { From 7ee46c214f6122f9758b9b06542337887c773b3e Mon Sep 17 00:00:00 2001 From: ferhatb Date: Thu, 25 Mar 2021 09:03:09 -0700 Subject: [PATCH 4/5] update golden locks --- lib/web_ui/dev/goldens_lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/dev/goldens_lock.yaml b/lib/web_ui/dev/goldens_lock.yaml index 5ea3b09d599e3..23544ce2a803f 100644 --- a/lib/web_ui/dev/goldens_lock.yaml +++ b/lib/web_ui/dev/goldens_lock.yaml @@ -1,2 +1,2 @@ repository: https://github.com/flutter/goldens.git -revision: c5f999871e83142afb82a636e97bd67a62789c6e +revision: 0c09e67a17eecc0c0c936f28d9138c1aa39a5043 From 0b4ef2a844f2050281566123ff7df6f7f95597bb Mon Sep 17 00:00:00 2001 From: ferhatb Date: Thu, 25 Mar 2021 09:39:23 -0700 Subject: [PATCH 5/5] update golden locks --- lib/web_ui/dev/goldens_lock.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/web_ui/dev/goldens_lock.yaml b/lib/web_ui/dev/goldens_lock.yaml index 23544ce2a803f..72d0359c70d78 100644 --- a/lib/web_ui/dev/goldens_lock.yaml +++ b/lib/web_ui/dev/goldens_lock.yaml @@ -1,2 +1,2 @@ repository: https://github.com/flutter/goldens.git -revision: 0c09e67a17eecc0c0c936f28d9138c1aa39a5043 +revision: 02ca90916f341a215d44fab6a13fefa7e865c372