Skip to content

Commit d41e25b

Browse files
authored
Revert "Revert "fix shadows and mask filter blurs (flutter#16963)" (flutter#17008)" (flutter#17040)
This reverts 619acd5 and re-lands 6cfa7fc. The 6cfa7fc was good. The screenshot changes were expected. Fixes flutter#32215
1 parent 7f942f2 commit d41e25b

File tree

11 files changed

+582
-450
lines changed

11 files changed

+582
-450
lines changed

lib/web_ui/dev/goldens_lock.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
repository: https://github.com/flutter/goldens.git
2-
revision: 1699ba6fd7093a0a610f82618fa30546e7974777
2+
revision: 8f692819e8881b7d2131dbd61d965c21d5e3e345

lib/web_ui/lib/src/engine/bitmap_canvas.dart

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -353,17 +353,16 @@ class BitmapCanvas extends EngineCanvas {
353353

354354
@override
355355
void drawImage(ui.Image image, ui.Offset p, SurfacePaintData paint) {
356-
//_applyPaint(paint);
357-
final HtmlImage htmlImage = image;
358-
final html.ImageElement imgElement = htmlImage.cloneImageElement();
359-
String blendMode = _stringForBlendMode(paint.blendMode);
360-
imgElement.style.mixBlendMode = blendMode;
361-
_drawImage(imgElement, p);
356+
_drawImage(image, p, paint);
362357
_childOverdraw = true;
363358
_canvasPool.allocateExtraCanvas();
364359
}
365360

366-
void _drawImage(html.ImageElement imgElement, ui.Offset p) {
361+
html.ImageElement _drawImage(ui.Image image, ui.Offset p, SurfacePaintData paint) {
362+
final HtmlImage htmlImage = image;
363+
final html.Element imgElement = htmlImage.cloneImageElement();
364+
final ui.BlendMode blendMode = paint.blendMode;
365+
imgElement.style.mixBlendMode = _stringForBlendMode(blendMode);
367366
if (_canvasPool.isClipped) {
368367
final List<html.Element> clipElements = _clipContent(
369368
_canvasPool._clipStack, imgElement, p, _canvasPool.currentTransform);
@@ -380,12 +379,12 @@ class BitmapCanvas extends EngineCanvas {
380379
rootElement.append(imgElement);
381380
_children.add(imgElement);
382381
}
382+
return imgElement;
383383
}
384384

385385
@override
386386
void drawImageRect(
387387
ui.Image image, ui.Rect src, ui.Rect dst, SurfacePaintData paint) {
388-
final HtmlImage htmlImage = image;
389388
final bool requiresClipping = src.left != 0 ||
390389
src.top != 0 ||
391390
src.width != image.width ||
@@ -395,9 +394,6 @@ class BitmapCanvas extends EngineCanvas {
395394
!requiresClipping) {
396395
drawImage(image, dst.topLeft, paint);
397396
} else {
398-
final html.Element imgElement = htmlImage.cloneImageElement();
399-
final ui.BlendMode blendMode = paint.blendMode;
400-
imgElement.style.mixBlendMode = _stringForBlendMode(blendMode);
401397
if (requiresClipping) {
402398
save();
403399
clipRect(dst);
@@ -414,7 +410,8 @@ class BitmapCanvas extends EngineCanvas {
414410
targetTop += topMargin;
415411
}
416412
}
417-
_drawImage(imgElement, ui.Offset(targetLeft, targetTop));
413+
414+
final html.ImageElement imgElement = _drawImage(image, ui.Offset(targetLeft, targetTop), paint);
418415
// To scale set width / height on destination image.
419416
// For clipping we need to scale according to
420417
// clipped-width/full image width and shift it according to left/top of

lib/web_ui/lib/src/engine/canvas_pool.dart

Lines changed: 40 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -581,49 +581,46 @@ class _CanvasPool extends _SaveStackTracking {
581581

582582
void drawShadow(ui.Path path, ui.Color color, double elevation,
583583
bool transparentOccluder) {
584-
final List<CanvasShadow> shadows =
585-
ElevationShadow.computeCanvasShadows(elevation, color);
586-
if (shadows.isNotEmpty) {
587-
for (final CanvasShadow shadow in shadows) {
588-
// TODO(het): Shadows with transparent occluders are not supported
589-
// on webkit since filter is unsupported.
590-
if (transparentOccluder && browserEngine != BrowserEngine.webkit) {
591-
// We paint shadows using a path and a mask filter instead of the
592-
// built-in shadow* properties. This is because the color alpha of the
593-
// paint is added to the shadow. The effect we're looking for is to just
594-
// paint the shadow without the path itself, but if we use a non-zero
595-
// alpha for the paint the path is painted in addition to the shadow,
596-
// which is undesirable.
597-
context.save();
598-
context.translate(shadow.offsetX, shadow.offsetY);
599-
context.filter = _maskFilterToCss(
600-
ui.MaskFilter.blur(ui.BlurStyle.normal, shadow.blur));
601-
context.strokeStyle = '';
602-
context.fillStyle = colorToCssString(shadow.color);
603-
_runPath(context, path);
604-
context.fill();
605-
context.restore();
606-
} else {
607-
// TODO(het): We fill the path with this paint, then later we clip
608-
// by the same path and fill it with a fully opaque color (we know
609-
// the color is fully opaque because `transparentOccluder` is false.
610-
// However, due to anti-aliasing of the clip, a few pixels of the
611-
// path we are about to paint may still be visible after we fill with
612-
// the opaque occluder. For that reason, we fill with the shadow color,
613-
// and set the shadow color to fully opaque. This way, the visible
614-
// pixels are less opaque and less noticeable.
615-
context.save();
616-
context.filter = 'none';
617-
context.strokeStyle = '';
618-
context.fillStyle = colorToCssString(shadow.color);
619-
context.shadowBlur = shadow.blur;
620-
context.shadowColor = colorToCssString(shadow.color.withAlpha(0xff));
621-
context.shadowOffsetX = shadow.offsetX;
622-
context.shadowOffsetY = shadow.offsetY;
623-
_runPath(context, path);
624-
context.fill();
625-
context.restore();
626-
}
584+
final SurfaceShadowData shadow = computeShadow(path.getBounds(), elevation);
585+
if (shadow != null) {
586+
// TODO(het): Shadows with transparent occluders are not supported
587+
// on webkit since filter is unsupported.
588+
if (transparentOccluder && browserEngine != BrowserEngine.webkit) {
589+
// We paint shadows using a path and a mask filter instead of the
590+
// built-in shadow* properties. This is because the color alpha of the
591+
// paint is added to the shadow. The effect we're looking for is to just
592+
// paint the shadow without the path itself, but if we use a non-zero
593+
// alpha for the paint the path is painted in addition to the shadow,
594+
// which is undesirable.
595+
context.save();
596+
context.translate(shadow.offset.dx, shadow.offset.dy);
597+
context.filter = _maskFilterToCss(
598+
ui.MaskFilter.blur(ui.BlurStyle.normal, shadow.blurWidth));
599+
context.strokeStyle = '';
600+
context.fillStyle = colorToCssString(color);
601+
_runPath(context, path);
602+
context.fill();
603+
context.restore();
604+
} else {
605+
// TODO(het): We fill the path with this paint, then later we clip
606+
// by the same path and fill it with a fully opaque color (we know
607+
// the color is fully opaque because `transparentOccluder` is false.
608+
// However, due to anti-aliasing of the clip, a few pixels of the
609+
// path we are about to paint may still be visible after we fill with
610+
// the opaque occluder. For that reason, we fill with the shadow color,
611+
// and set the shadow color to fully opaque. This way, the visible
612+
// pixels are less opaque and less noticeable.
613+
context.save();
614+
context.filter = 'none';
615+
context.strokeStyle = '';
616+
context.fillStyle = colorToCssString(color);
617+
context.shadowBlur = shadow.blurWidth;
618+
context.shadowColor = colorToCssString(color.withAlpha(0xff));
619+
context.shadowOffsetX = shadow.offset.dx;
620+
context.shadowOffsetY = shadow.offset.dy;
621+
_runPath(context, path);
622+
context.fill();
623+
context.restore();
627624
}
628625
}
629626
}

lib/web_ui/lib/src/engine/compositor/util.dart

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,10 +286,6 @@ js.JsArray<double> makeSkiaColorStops(List<double> colorStops) {
286286
return jsColorStops;
287287
}
288288

289-
// These must be kept in sync with `flow/layers/physical_shape_layer.cc`.
290-
const double kLightHeight = 600.0;
291-
const double kLightRadius = 800.0;
292-
293289
void drawSkShadow(
294290
js.JsObject skCanvas,
295291
SkPath path,

lib/web_ui/lib/src/engine/dom_canvas.dart

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,15 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
8181
}());
8282
String effectiveTransform;
8383
final bool isStroke = paint.style == ui.PaintingStyle.stroke;
84+
final double strokeWidth = paint.strokeWidth ?? 0.0;
8485
final double left = math.min(rect.left, rect.right);
8586
final double right = math.max(rect.left, rect.right);
8687
final double top = math.min(rect.top, rect.bottom);
8788
final double bottom = math.max(rect.top, rect.bottom);
8889
if (currentTransform.isIdentity()) {
8990
if (isStroke) {
9091
effectiveTransform =
91-
'translate(${left - (paint.strokeWidth / 2.0)}px, ${top - (paint.strokeWidth / 2.0)}px)';
92+
'translate(${left - (strokeWidth / 2.0)}px, ${top - (strokeWidth / 2.0)}px)';
9293
} else {
9394
effectiveTransform = 'translate(${left}px, ${top}px)';
9495
}
@@ -97,7 +98,7 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
9798
final Matrix4 translated = currentTransform.clone();
9899
if (isStroke) {
99100
translated.translate(
100-
left - (paint.strokeWidth / 2.0), top - (paint.strokeWidth / 2.0));
101+
left - (strokeWidth / 2.0), top - (strokeWidth / 2.0));
101102
} else {
102103
translated.translate(left, top);
103104
}
@@ -109,18 +110,18 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
109110
..transformOrigin = '0 0 0'
110111
..transform = effectiveTransform;
111112

112-
final String cssColor = paint.color == null ? '#000000'
113-
: colorToCssString(paint.color);
113+
final String cssColor =
114+
paint.color == null ? '#000000' : colorToCssString(paint.color);
114115

115116
if (paint.maskFilter != null) {
116117
style.filter = 'blur(${paint.maskFilter.webOnlySigma}px)';
117118
}
118119

119120
if (isStroke) {
120121
style
121-
..width = '${right - left - paint.strokeWidth}px'
122-
..height = '${bottom - top - paint.strokeWidth}px'
123-
..border = '${paint.strokeWidth}px solid $cssColor';
122+
..width = '${right - left - strokeWidth}px'
123+
..height = '${bottom - top - strokeWidth}px'
124+
..border = '${strokeWidth}px solid $cssColor';
124125
} else {
125126
style
126127
..width = '${right - left}px'

0 commit comments

Comments
 (0)