Commit 0c2546c6 authored by Ian Hickson's avatar Ian Hickson Committed by GitHub

Factor out some common code in PaintingContext (#10607)

...and remove some highly specialised methods now that they can just
be implemented directly by the previous callers.
parent 09eba82a
...@@ -12,6 +12,7 @@ import 'package:vector_math/vector_math_64.dart'; ...@@ -12,6 +12,7 @@ import 'package:vector_math/vector_math_64.dart';
import 'box.dart'; import 'box.dart';
import 'debug.dart'; import 'debug.dart';
import 'layer.dart';
import 'object.dart'; import 'object.dart';
import 'semantics.dart'; import 'semantics.dart';
...@@ -837,8 +838,15 @@ class RenderShaderMask extends RenderProxyBox { ...@@ -837,8 +838,15 @@ class RenderShaderMask extends RenderProxyBox {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
assert(needsCompositing); assert(needsCompositing);
final Shader shader = _shaderCallback(offset & size); context.pushLayer(
context.pushShaderMask(offset, shader, Offset.zero & size, _blendMode, super.paint); new ShaderMaskLayer(
shader: _shaderCallback(offset & size),
maskRect: offset & size,
blendMode: _blendMode,
),
super.paint,
offset,
);
} }
} }
} }
...@@ -878,7 +886,7 @@ class RenderBackdropFilter extends RenderProxyBox { ...@@ -878,7 +886,7 @@ class RenderBackdropFilter extends RenderProxyBox {
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
assert(needsCompositing); assert(needsCompositing);
context.pushBackdropFilter(offset, _filter, super.paint); context.pushLayer(new BackdropFilterLayer(filter: _filter), super.paint, offset);
} }
} }
} }
...@@ -1308,11 +1316,47 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> { ...@@ -1308,11 +1316,47 @@ class RenderPhysicalModel extends _RenderCustomClip<RRect> {
return super.hitTest(result, position: position); return super.hitTest(result, position: position);
} }
static final Paint _defaultPaint = new Paint();
static final Paint _transparentPaint = new Paint()..color = const Color(0x00000000);
@override @override
void paint(PaintingContext context, Offset offset) { void paint(PaintingContext context, Offset offset) {
if (child != null) { if (child != null) {
_updateClip(); _updateClip();
context.pushPhysicalModel(needsCompositing, offset, _clip.outerRect, _clip, elevation, color, super.paint); final RRect offsetClipRRect = _clip.shift(offset);
final Rect offsetBounds = offsetClipRRect.outerRect;
if (needsCompositing) {
final PhysicalModelLayer physicalModel = new PhysicalModelLayer(
clipRRect: offsetClipRRect,
elevation: elevation,
color: color,
);
context.pushLayer(physicalModel, super.paint, offset, childPaintBounds: offsetBounds);
} else {
final Canvas canvas = context.canvas;
if (elevation != 0.0) {
// The drawShadow call doesn't add the region of the shadow to the
// picture's bounds, so we draw a hardcoded amount of extra space to
// account for the maximum potential area of the shadow.
// TODO(jsimmons): remove this when Skia does it for us.
canvas.drawRect(
offsetBounds.inflate(20.0),
_transparentPaint,
);
canvas.drawShadow(
new Path()..addRRect(offsetClipRRect),
const Color(0xFF000000),
elevation,
color.alpha != 0xFF,
);
}
canvas.drawRRect(offsetClipRRect, new Paint()..color = color);
canvas.saveLayer(offsetBounds, _defaultPaint);
canvas.clipRRect(offsetClipRRect);
super.paint(context, offset);
canvas.restore();
assert(context.canvas == canvas, 'canvas changed even though needsCompositing was false');
}
} }
} }
......
...@@ -96,10 +96,10 @@ void main() { ...@@ -96,10 +96,10 @@ void main() {
expect(widget1InitialTopLeft.dy == widget2TopLeft.dy, true); expect(widget1InitialTopLeft.dy == widget2TopLeft.dy, true);
// Page 2 is coming in from the right. // Page 2 is coming in from the right.
expect(widget2TopLeft.dx > widget1InitialTopLeft.dx, true); expect(widget2TopLeft.dx > widget1InitialTopLeft.dx, true);
// The shadow should be drawn to one screen width to the left of where // The shadow should be drawn to one screen width to the left of where
// the page 2 box is. `paints` tests relative to the painter's given canvas // the page 2 box is. `paints` tests relative to the painter's given canvas
// rather than relative to the screen so assert that it's one screen // rather than relative to the screen so assert that it's one screen
// width to the left of 0 offset box rect and nothing is drawn inside the // width to the left of 0 offset box rect and nothing is drawn inside the
// box's rect. // box's rect.
expect(box, paints..rect( expect(box, paints..rect(
rect: new Rect.fromLTWH(-800.0, 0.0, 800.0, 600.0) rect: new Rect.fromLTWH(-800.0, 0.0, 800.0, 600.0)
......
...@@ -38,6 +38,12 @@ class TestRecordingCanvas implements Canvas { ...@@ -38,6 +38,12 @@ class TestRecordingCanvas implements Canvas {
invocations.add(new _MethodCall(#save)); invocations.add(new _MethodCall(#save));
} }
@override
void saveLayer(Rect bounds, Paint paint) {
_saveCount += 1;
invocations.add(new _MethodCall(#saveLayer, <dynamic>[bounds, paint]));
}
@override @override
void restore() { void restore() {
_saveCount -= 1; _saveCount -= 1;
...@@ -77,8 +83,9 @@ class TestRecordingPaintingContext implements PaintingContext { ...@@ -77,8 +83,9 @@ class TestRecordingPaintingContext implements PaintingContext {
} }
class _MethodCall implements Invocation { class _MethodCall implements Invocation {
_MethodCall(this._name); _MethodCall(this._name, [ this._arguments = const <dynamic>[] ]);
final Symbol _name; final Symbol _name;
final List<dynamic> _arguments;
@override @override
bool get isAccessor => false; bool get isAccessor => false;
@override @override
...@@ -92,5 +99,5 @@ class _MethodCall implements Invocation { ...@@ -92,5 +99,5 @@ class _MethodCall implements Invocation {
@override @override
Map<Symbol, dynamic> get namedArguments => <Symbol, dynamic>{}; Map<Symbol, dynamic> get namedArguments => <Symbol, dynamic>{};
@override @override
List<dynamic> get positionalArguments => <dynamic>[]; List<dynamic> get positionalArguments => _arguments;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment