diff --git a/packages/flutter/lib/src/material/time_picker.dart b/packages/flutter/lib/src/material/time_picker.dart index 1e3a61cc66..cca45f07ed 100644 --- a/packages/flutter/lib/src/material/time_picker.dart +++ b/packages/flutter/lib/src/material/time_picker.dart @@ -429,7 +429,7 @@ class _DialPainter extends CustomPainter { center: focusedPoint, radius: focusedRadius ); canvas - ..saveLayer(focusedRect, new Paint()) + ..save() ..clipPath(new Path()..addOval(focusedRect)); paintLabels(secondaryLabels); canvas.restore(); diff --git a/packages/flutter/lib/src/painting/flutter_logo.dart b/packages/flutter/lib/src/painting/flutter_logo.dart index fa712d411c..64ae1a628b 100644 --- a/packages/flutter/lib/src/painting/flutter_logo.dart +++ b/packages/flutter/lib/src/painting/flutter_logo.dart @@ -466,6 +466,7 @@ class _FlutterLogoPainter extends BoxPainter { final double fontSize = 0.35 * logoTargetSquare.height * (1 - (10.4 * 2.0) / 202.0); final double scale = fontSize / 100.0; if (_config._position > -1.0) { + // This limits what the drawRect call below is going to blend with. canvas.saveLayer(_textBoundingRect, new Paint()); } else { canvas.save(); diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 96235f1592..f31212e7e6 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -330,10 +330,12 @@ class PaintingContext { if (needsCompositing) { pushLayer(new ClipRectLayer(clipRect: offsetClipRect), painter, offset, childPaintBounds: offsetClipRect); } else { - canvas.save(); - canvas.clipRect(offsetClipRect); + canvas + ..save() + ..clipRect(offsetClipRect); painter(this, offset); - canvas.restore(); + canvas + ..restore(); } } @@ -355,10 +357,14 @@ class PaintingContext { if (needsCompositing) { pushLayer(new ClipRRectLayer(clipRRect: offsetClipRRect), painter, offset, childPaintBounds: offsetBounds); } else { - canvas.saveLayer(offsetBounds, _defaultPaint); - canvas.clipRRect(offsetClipRRect); + canvas + ..save() + ..clipRRect(offsetClipRRect) + ..saveLayer(offsetBounds, _defaultPaint); painter(this, offset); - canvas.restore(); + canvas + ..restore() + ..restore(); } } @@ -380,10 +386,14 @@ class PaintingContext { if (needsCompositing) { pushLayer(new ClipPathLayer(clipPath: offsetClipPath), painter, offset, childPaintBounds: offsetBounds); } else { - canvas.saveLayer(bounds.shift(offset), _defaultPaint); - canvas.clipPath(clipPath.shift(offset)); + canvas + ..save() + ..clipPath(clipPath.shift(offset)) + ..saveLayer(bounds.shift(offset), _defaultPaint); painter(this, offset); - canvas.restore(); + canvas + ..restore() + ..restore(); } } @@ -407,10 +417,12 @@ class PaintingContext { childPaintBounds: MatrixUtils.inverseTransformRect(effectiveTransform, canvasBounds), ); } else { - canvas.save(); - canvas.transform(effectiveTransform.storage); + canvas + ..save() + ..transform(effectiveTransform.storage); painter(this, offset); - canvas.restore(); + canvas + ..restore(); } } diff --git a/packages/flutter/lib/src/rendering/paragraph.dart b/packages/flutter/lib/src/rendering/paragraph.dart index 7f254205a3..c10c7bded1 100644 --- a/packages/flutter/lib/src/rendering/paragraph.dart +++ b/packages/flutter/lib/src/rendering/paragraph.dart @@ -297,10 +297,13 @@ class RenderParagraph extends RenderBox { if (_hasVisualOverflow) { final Rect bounds = offset & size; - if (_overflowShader != null) + if (_overflowShader != null) { + // This layer limits what the shader below blends with to be just the text + // (as opposed to the text and its background). canvas.saveLayer(bounds, new Paint()); - else + } else { canvas.save(); + } canvas.clipRect(bounds); } _textPainter.paint(canvas, offset); diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index 1fc6b3e428..441a77fc94 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -1351,13 +1351,19 @@ class RenderPhysicalModel extends _RenderCustomClip { ); } canvas.drawRRect(offsetClipRRect, new Paint()..color = color); - if (offsetClipRRect.isRect) { - canvas.save(); - } else { - canvas.saveLayer(offsetBounds, _defaultPaint); - } + canvas.save(); canvas.clipRRect(offsetClipRRect); + // We only use a new layer for non-rectangular clips, on the basis that + // rectangular clips won't need antialiasing. This is not really + // correct, because if we're e.g. rotated, rectangles will also be + // aliased. Unfortunately, it's too much of a performance win to err on + // the side of correctness here. + // TODO(ianh): Find a better solution. + if (!offsetClipRRect.isRect) + canvas.saveLayer(offsetBounds, _defaultPaint); super.paint(context, offset); + if (!offsetClipRRect.isRect) + canvas.restore(); canvas.restore(); assert(context.canvas == canvas, 'canvas changed even though needsCompositing was false'); }