Do not apply the canvas bounds as a cull rectangle when recording a Skia picture (#14027)
The picture may need to draw outside the bounds (specifically for shadows) Fixes https://github.com/flutter/flutter/issues/12618
This commit is contained in:
parent
a67df9e1d1
commit
0434ae22ec
@ -59,25 +59,19 @@ typedef void PaintingContextCallback(PaintingContext context, Offset offset);
|
||||
/// New [PaintingContext] objects are created automatically when using
|
||||
/// [PaintingContext.repaintCompositedChild] and [pushLayer].
|
||||
class PaintingContext {
|
||||
PaintingContext._(this._containerLayer, this.canvasBounds)
|
||||
PaintingContext._(this._containerLayer, this.estimatedBounds)
|
||||
: assert(_containerLayer != null),
|
||||
assert(canvasBounds != null);
|
||||
assert(estimatedBounds != null);
|
||||
|
||||
final ContainerLayer _containerLayer;
|
||||
|
||||
/// The bounds within which the painting context's [canvas] will record
|
||||
/// painting commands.
|
||||
/// An estimate of the bounds within which the painting context's [canvas]
|
||||
/// will record painting commands. This can be useful for debugging.
|
||||
///
|
||||
/// A render object provided with this [PaintingContext] (e.g. in its
|
||||
/// [RenderObject.paint] method) is permitted to paint outside the region that
|
||||
/// the render object occupies during layout, but is not permitted to paint
|
||||
/// outside these canvas paints bounds. These paint bounds are used to
|
||||
/// construct memory-efficient composited layers, which means attempting to
|
||||
/// paint outside these bounds can attempt to write to pixels that do not
|
||||
/// exist in the composited layer.
|
||||
/// The canvas will allow painting outside these bounds.
|
||||
///
|
||||
/// The [canvasBounds] rectangle is in the [canvas] coordinate system.
|
||||
final Rect canvasBounds;
|
||||
/// The [estimatedBounds] rectangle is in the [canvas] coordinate system.
|
||||
final Rect estimatedBounds;
|
||||
|
||||
/// Repaint the given render object.
|
||||
///
|
||||
@ -200,8 +194,6 @@ class PaintingContext {
|
||||
/// The current canvas can change whenever you paint a child using this
|
||||
/// context, which means it's fragile to hold a reference to the canvas
|
||||
/// returned by this getter.
|
||||
///
|
||||
/// Only calls within the [canvasBounds] will be recorded.
|
||||
Canvas get canvas {
|
||||
if (_canvas == null)
|
||||
_startRecording();
|
||||
@ -210,9 +202,9 @@ class PaintingContext {
|
||||
|
||||
void _startRecording() {
|
||||
assert(!_isRecording);
|
||||
_currentLayer = new PictureLayer(canvasBounds);
|
||||
_currentLayer = new PictureLayer(estimatedBounds);
|
||||
_recorder = new ui.PictureRecorder();
|
||||
_canvas = new Canvas(_recorder, canvasBounds);
|
||||
_canvas = new Canvas(_recorder);
|
||||
_containerLayer.append(_currentLayer);
|
||||
}
|
||||
|
||||
@ -225,14 +217,14 @@ class PaintingContext {
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 6.0
|
||||
..color = debugCurrentRepaintColor.toColor();
|
||||
canvas.drawRect(canvasBounds.deflate(3.0), paint);
|
||||
canvas.drawRect(estimatedBounds.deflate(3.0), paint);
|
||||
}
|
||||
if (debugPaintLayerBordersEnabled) {
|
||||
final Paint paint = new Paint()
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1.0
|
||||
..color = const Color(0xFFFF9800);
|
||||
canvas.drawRect(canvasBounds, paint);
|
||||
canvas.drawRect(estimatedBounds, paint);
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
@ -284,9 +276,9 @@ class PaintingContext {
|
||||
}
|
||||
|
||||
/// Appends the given layer to the recording, and calls the `painter` callback
|
||||
/// with that layer, providing the `childPaintBounds` as the paint bounds of
|
||||
/// the child. Canvas recording commands are not guaranteed to be stored
|
||||
/// outside of the paint bounds.
|
||||
/// with that layer, providing the `childPaintBounds` as the estimated paint
|
||||
/// bounds of the child. The `childPaintBounds` can be used for debugging but
|
||||
/// have no effect on painting.
|
||||
///
|
||||
/// The given layer must be an unattached orphan. (Providing a newly created
|
||||
/// object, rather than reusing an existing layer, satisfies that
|
||||
@ -309,7 +301,7 @@ class PaintingContext {
|
||||
assert(painter != null);
|
||||
_stopRecordingIfNeeded();
|
||||
_appendLayer(childLayer);
|
||||
final PaintingContext childContext = new PaintingContext._(childLayer, childPaintBounds ?? canvasBounds);
|
||||
final PaintingContext childContext = new PaintingContext._(childLayer, childPaintBounds ?? estimatedBounds);
|
||||
painter(childContext, offset);
|
||||
childContext._stopRecordingIfNeeded();
|
||||
}
|
||||
@ -413,7 +405,7 @@ class PaintingContext {
|
||||
new TransformLayer(transform: effectiveTransform),
|
||||
painter,
|
||||
offset,
|
||||
childPaintBounds: MatrixUtils.inverseTransformRect(effectiveTransform, canvasBounds),
|
||||
childPaintBounds: MatrixUtils.inverseTransformRect(effectiveTransform, estimatedBounds),
|
||||
);
|
||||
} else {
|
||||
canvas
|
||||
@ -444,7 +436,7 @@ class PaintingContext {
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() => '$runtimeType#$hashCode(layer: $_containerLayer, canvas bounds: $canvasBounds)';
|
||||
String toString() => '$runtimeType#$hashCode(layer: $_containerLayer, canvas bounds: $estimatedBounds)';
|
||||
}
|
||||
|
||||
/// An abstract set of layout constraints.
|
||||
@ -2037,17 +2029,8 @@ abstract class RenderObject extends AbstractNode with DiagnosticableTreeMixin im
|
||||
}());
|
||||
}
|
||||
|
||||
/// The bounds within which this render object will paint.
|
||||
///
|
||||
/// A render object and its descendants are permitted to paint outside the
|
||||
/// region it occupies during layout, but they are not permitted to paint
|
||||
/// outside these paints bounds. These paint bounds are used to construct
|
||||
/// memory-efficient composited layers, which means attempting to paint
|
||||
/// outside these bounds can attempt to write to pixels that do not exist in
|
||||
/// this render object's composited layer.
|
||||
///
|
||||
/// The [paintBounds] are only actually enforced when the render object is a
|
||||
/// repaint boundary; see [isRepaintBoundary].
|
||||
/// An estimate of the bounds within which this render object will paint.
|
||||
/// Useful for debugging flags such as [debugPaintLayerBordersEnabled].
|
||||
Rect get paintBounds;
|
||||
|
||||
/// Override this method to paint debugging information.
|
||||
|
Loading…
x
Reference in New Issue
Block a user