Chromium Code Reviews| Index: third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| diff --git a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| index a4532342b20abde458b054ea1f543759e5489bb1..698371df26596cb6f6e952917609fad1499324d6 100644 |
| --- a/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| +++ b/third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp |
| @@ -19,7 +19,7 @@ FloatRect GeometryMapper::mapToVisualRectInDestinationSpace(const FloatRect& rec |
| FloatRect result = localToVisualRectInAncestorSpace(rect, sourceState, destinationState, success); |
| if (success) |
| return result; |
| - return slowMapRectToDestinationSpace(rect, sourceState, destinationState, success); |
| + return slowMapToVisualRectInDestinationSpace(rect, sourceState, destinationState, success); |
| } |
| FloatRect GeometryMapper::mapRectToDestinationSpace(const FloatRect& rect, |
| @@ -33,6 +33,36 @@ FloatRect GeometryMapper::mapRectToDestinationSpace(const FloatRect& rect, |
| return slowMapRectToDestinationSpace(rect, sourceState, destinationState, success); |
| } |
| +FloatRect GeometryMapper::slowMapToVisualRectInDestinationSpace(const FloatRect& rect, |
| + const PropertyTreeState& sourceState, |
| + const PropertyTreeState& destinationState, |
| + bool& success) |
| +{ |
| + const TransformPaintPropertyNode* lcaTransform = propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState.transform.get()); |
| + DCHECK(lcaTransform); |
| + PropertyTreeState lcaState = sourceState; |
| + lcaState.transform = lcaTransform; |
| + |
| + FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success); |
| + DCHECK(success); |
| + |
| + // It's a failure if the clip of destinationState is not an ancestor of the clip of sourceState, |
| + // because otherwise we can't undo the clips from the common ancestor to destinationState. |
| + const auto clipRect = localToAncestorClipRect(sourceState, destinationState, success); |
| + if (!success) |
| + return result; |
| + result.intersect(clipRect); |
| + |
| + const TransformationMatrix& destinationToLca = localToAncestorMatrix(destinationState.transform.get(), lcaState, success); |
| + DCHECK(success); |
| + if (destinationToLca.isInvertible()) { |
| + success = true; |
| + return destinationToLca.inverse().mapRect(result); |
| + } |
| + success = false; |
| + return rect; |
| +} |
| + |
| FloatRect GeometryMapper::slowMapRectToDestinationSpace(const FloatRect& rect, |
| const PropertyTreeState& sourceState, |
| const PropertyTreeState& destinationState, |
| @@ -61,13 +91,14 @@ FloatRect GeometryMapper::localToVisualRectInAncestorSpace( |
| const PropertyTreeState& localState, |
| const PropertyTreeState& ancestorState, bool& success) |
| { |
| - const auto transformMatrix = localToAncestorMatrix(localState.transform.get(), ancestorState, success); |
| + const auto& transformMatrix = localToAncestorMatrix(localState.transform.get(), ancestorState, success); |
| if (!success) |
| return rect; |
| FloatRect mappedRect = transformMatrix.mapRect(rect); |
| - const auto clipRect = localToAncestorClipRect(localState, ancestorState); |
| + const auto clipRect = localToAncestorClipRect(localState, ancestorState, success); |
| + DCHECK(success); |
| mappedRect.intersect(clipRect); |
| return mappedRect; |
| @@ -79,7 +110,7 @@ FloatRect GeometryMapper::localToAncestorRect( |
| const PropertyTreeState& ancestorState, |
| bool& success) |
| { |
| - const auto transformMatrix = localToAncestorMatrix(localState.transform.get(), ancestorState, success); |
| + const auto& transformMatrix = localToAncestorMatrix(localState.transform.get(), ancestorState, success); |
| if (!success) |
| return rect; |
| return transformMatrix.mapRect(rect); |
| @@ -112,9 +143,10 @@ PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(const |
| return *addResult.storedValue->value; |
| } |
| -const FloatRect& GeometryMapper::localToAncestorClipRect( |
| +FloatRect GeometryMapper::localToAncestorClipRect( |
| const PropertyTreeState& localState, |
| - const PropertyTreeState& ancestorState) |
| + const PropertyTreeState& ancestorState, |
| + bool& success) |
| { |
| PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor(ancestorState); |
| const ClipPaintPropertyNode* clipNode = localState.clip.get(); |
| @@ -139,12 +171,14 @@ const FloatRect& GeometryMapper::localToAncestorClipRect( |
| clipNode = clipNode->parent(); |
| } |
| // It's illegal to ask for a local-to-ancestor clip when the ancestor is not an ancestor. |
|
chrishtr
2016/08/22 22:27:31
Remove this comment.
Xianzhu
2016/08/22 23:30:20
Done.
|
| - DCHECK(clipNode == ancestorState.clip || found); |
| + if (clipNode != ancestorState.clip && !found) { |
| + success = false; |
| + return LayoutRect::infiniteIntRect(); |
| + } |
| // Iterate down from the top intermediate node found in the previous loop, computing and memoizing clip rects as we go. |
| for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); ++it) { |
| if ((*it) != ancestorState.clip) { |
| - bool success = false; |
|
chrishtr
2016/08/22 22:27:31
Why remove this line? Reset success to false each
Xianzhu
2016/08/22 23:30:20
Changed to
success = false;
const Tr
|
| const TransformationMatrix transformMatrix = localToAncestorMatrix((*it)->localTransformSpace(), ancestorState, success); |
| DCHECK(success); |
| FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rect()); |
| @@ -157,7 +191,6 @@ const FloatRect& GeometryMapper::localToAncestorClipRect( |
| return precomputedData.toAncestorClipRects.find(localState.clip.get())->value; |
| } |
| - |
| const TransformationMatrix& GeometryMapper::localToAncestorMatrix( |
| const TransformPaintPropertyNode* localTransformNode, |
| const PropertyTreeState& ancestorState, bool& success) { |