diff --git a/packages/flutter/lib/src/material/material.dart b/packages/flutter/lib/src/material/material.dart index de3b8909c8..922d75ffdf 100644 --- a/packages/flutter/lib/src/material/material.dart +++ b/packages/flutter/lib/src/material/material.dart @@ -298,17 +298,18 @@ abstract class InkFeature { assert(referenceBox.attached); assert(!_debugDisposed); // find the chain of renderers from us to the feature's referenceBox - List descendants = []; + List descendants = [referenceBox]; RenderBox node = referenceBox; while (node != renderer) { - descendants.add(node); node = node.parent; assert(node != null); + descendants.add(node); } // determine the transform that gets our coordinate system to be like theirs Matrix4 transform = new Matrix4.identity(); - for (RenderBox descendant in descendants.reversed) - descendant.applyPaintTransform(transform); + assert(descendants.length >= 2); + for (int index = descendants.length - 1; index > 0; index -= 1) + descendants[index].applyPaintTransform(descendants[index - 1], transform); paintFeature(canvas, transform); } diff --git a/packages/flutter/lib/src/rendering/block.dart b/packages/flutter/lib/src/rendering/block.dart index a1c4e33772..96edfa31e3 100644 --- a/packages/flutter/lib/src/rendering/block.dart +++ b/packages/flutter/lib/src/rendering/block.dart @@ -420,12 +420,12 @@ class RenderBlockViewport extends RenderBlockBase { context.pushClipRect(needsCompositing, offset, Point.origin & size, _paintContents); } - void applyPaintTransform(Matrix4 transform) { - super.applyPaintTransform(transform); + void applyPaintTransform(RenderBox child, Matrix4 transform) { if (isVertical) transform.translate(0.0, startOffset); else transform.translate(startOffset, 0.0); + super.applyPaintTransform(child, transform); } bool hitTestChildren(HitTestResult result, { Point position }) { diff --git a/packages/flutter/lib/src/rendering/box.dart b/packages/flutter/lib/src/rendering/box.dart index ced458e548..4c57d4332e 100644 --- a/packages/flutter/lib/src/rendering/box.dart +++ b/packages/flutter/lib/src/rendering/box.dart @@ -609,49 +609,53 @@ abstract class RenderBox extends RenderObject { /// visually "on top" (i.e., paints later). bool hitTestChildren(HitTestResult result, { Point position }) => false; - /// Multiply the transform from the parent's coordinate system to this box's - /// coordinate system into the given transform - /// - /// This function is used to convert coordinate systems between boxes. - /// Subclasses that apply transforms during painting should override this - /// function to factor those transforms into the calculation. - void applyPaintTransform(Matrix4 transform) { - if (parentData is BoxParentData) { - Point position = (parentData as BoxParentData).position; - transform.translate(position.x, position.y); - } - } - static Point _transformPoint(Matrix4 transform, Point point) { Vector3 position3 = new Vector3(point.x, point.y, 0.0); Vector3 transformed3 = transform.transform3(position3); return new Point(transformed3.x, transformed3.y); } + /// Multiply the transform from the parent's coordinate system to this box's + /// coordinate system into the given transform. + /// + /// This function is used to convert coordinate systems between boxes. + /// Subclasses that apply transforms during painting should override this + /// function to factor those transforms into the calculation. + /// + /// The RenderBox implementation takes care of adjusting the matrix for the + /// position of the given child. + void applyPaintTransform(RenderObject child, Matrix4 transform) { + assert(child.parent == this); + BoxParentData childParentData = child.parentData; + Point position = childParentData.position; + transform.translate(position.x, position.y); + } + /// Convert the given point from the global coodinate system to the local /// coordinate system for this box Point globalToLocal(Point point) { assert(attached); Matrix4 transform = new Matrix4.identity(); RenderObject renderer = this; - while (renderer != null) { - renderer.applyPaintTransform(transform); - renderer = renderer.parent; + while (renderer.parent is RenderObject) { + RenderObject rendererParent = renderer.parent; + rendererParent.applyPaintTransform(renderer, transform); + renderer = rendererParent; } /* double det = */ transform.invert(); // TODO(abarth): Check the determinant for degeneracy. return _transformPoint(transform, point); } - /// Convert the given point from the local coordiante system for this box to - /// the global coordinate sytem + /// Convert the given point from the local coordinate system for this box to + /// the global coordinate system. Point localToGlobal(Point point) { List renderers = []; for (RenderObject renderer = this; renderer != null; renderer = renderer.parent) renderers.add(renderer); Matrix4 transform = new Matrix4.identity(); - for (RenderObject renderer in renderers.reversed) - renderer.applyPaintTransform(transform); + for (int index = renderers.length - 1; index > 0; index -= 1) + renderers[index].applyPaintTransform(renderers[index - 1], transform); return _transformPoint(transform, point); } diff --git a/packages/flutter/lib/src/rendering/object.dart b/packages/flutter/lib/src/rendering/object.dart index 176e009d1a..2a52f6ca01 100644 --- a/packages/flutter/lib/src/rendering/object.dart +++ b/packages/flutter/lib/src/rendering/object.dart @@ -1036,12 +1036,14 @@ abstract class RenderObject extends AbstractNode implements HitTestTarget { /// be recorded on separate compositing layers. void paint(PaintingContext context, Offset offset) { } - /// If this render object applies a transform before painting, apply that - /// transform to the given matrix + /// Applies the transform that would be applied when painting the given child + /// to the given matrix. /// /// Used by coordinate conversion functions to translate coordinates local to /// one render object into coordinates local to another render object. - void applyPaintTransform(Matrix4 transform) { } + void applyPaintTransform(RenderObject child, Matrix4 transform) { + assert(child.parent == this); + } // EVENTS diff --git a/packages/flutter/lib/src/rendering/proxy_box.dart b/packages/flutter/lib/src/rendering/proxy_box.dart index bbb60e033f..87b4e0667e 100644 --- a/packages/flutter/lib/src/rendering/proxy_box.dart +++ b/packages/flutter/lib/src/rendering/proxy_box.dart @@ -974,9 +974,9 @@ class RenderTransform extends RenderProxyBox { } } - void applyPaintTransform(Matrix4 transform) { - super.applyPaintTransform(transform); + void applyPaintTransform(RenderBox child, Matrix4 transform) { transform.multiply(_effectiveTransform); + super.applyPaintTransform(child, transform); } void debugDescribeSettings(List settings) { diff --git a/packages/flutter/lib/src/rendering/viewport.dart b/packages/flutter/lib/src/rendering/viewport.dart index eee9cb65ed..b3cfa192f5 100644 --- a/packages/flutter/lib/src/rendering/viewport.dart +++ b/packages/flutter/lib/src/rendering/viewport.dart @@ -164,9 +164,9 @@ class RenderViewport extends RenderBox with RenderObjectWithChildMixin