Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "platform/graphics/paint/GeometryMapper.h" | |
| 6 | |
| 7 #include "platform/geometry/LayoutRect.h" | |
| 8 #include "platform/graphics/paint/ClipPaintPropertyNode.h" | |
| 9 #include "platform/graphics/paint/EffectPaintPropertyNode.h" | |
| 10 #include "platform/graphics/paint/TransformPaintPropertyNode.h" | |
| 11 | |
| 12 namespace blink { | |
| 13 | |
| 14 FloatRect GeometryMapper::LocalToVisibleRectInAncestorSpace( | |
| 15 const FloatRect& rect, | |
| 16 const PropertyTreeState& localState, | |
| 17 const PropertyTreeState& ancestorState) | |
| 18 { | |
| 19 const auto transformMatrix = LocalToAncestorMatrix(localState.transform, anc estorState); | |
| 20 FloatRect mappedRect = transformMatrix.mapRect(rect); | |
| 21 | |
| 22 const auto clipRect = LocalToAncestorClipRect(localState, ancestorState); | |
| 23 | |
| 24 mappedRect.intersect(clipRect); | |
| 25 return mappedRect; | |
| 26 } | |
| 27 | |
| 28 FloatRect GeometryMapper::LocalToAncestorRect( | |
| 29 const FloatRect& rect, | |
| 30 const PropertyTreeState& localState, | |
| 31 const PropertyTreeState& ancestorState) | |
| 32 { | |
| 33 const auto transformMatrix = LocalToAncestorMatrix(localState.transform, anc estorState); | |
| 34 return transformMatrix.mapRect(rect); | |
| 35 } | |
| 36 | |
| 37 FloatRect GeometryMapper::AncestorToLocalRect( | |
| 38 const FloatRect& rect, | |
| 39 const PropertyTreeState& localState, | |
| 40 const PropertyTreeState& ancestorState, bool* success) | |
| 41 { | |
| 42 const auto& transformMatrix = LocalToAncestorMatrix(localState.transform, an cestorState); | |
| 43 if (!transformMatrix.isInvertible()) { | |
| 44 *success = false; | |
| 45 return FloatRect(); | |
| 46 } | |
| 47 *success = true; | |
| 48 | |
| 49 // TODO(chrishtr): Cache the inverse? | |
| 50 return transformMatrix.inverse().mapRect(rect); | |
| 51 } | |
| 52 | |
| 53 PrecomputedDataForAncestor* GeometryMapper::GetPrecomputedDataForAncestor(const PropertyTreeState& ancestorState) | |
|
Xianzhu
2016/06/22 23:20:30
Can this return a reference?
chrishtr
2016/06/23 00:18:26
Done.
| |
| 54 { | |
| 55 auto first = m_data.add(ancestorState.transform, PrecomputedDataForAncestor( )); | |
|
wkorman
2016/06/22 23:33:32
nit: believe this will always construct an empty P
chrishtr
2016/06/23 00:18:26
Done.
| |
| 56 auto second = first.storedValue; | |
| 57 return &second->value; | |
|
Xianzhu
2016/06/22 23:20:30
It looks not clear what 'first' and 'second' are.
chrishtr
2016/06/23 00:18:26
Done.
| |
| 58 } | |
| 59 | |
| 60 const FloatRect GeometryMapper::LocalToAncestorClipRect( | |
|
Xianzhu
2016/06/22 23:20:30
Return a reference?
chrishtr
2016/06/23 00:18:26
Done.
| |
| 61 const PropertyTreeState& localState, | |
| 62 const PropertyTreeState& ancestorState) | |
| 63 { | |
| 64 PrecomputedDataForAncestor* precomputedData = GetPrecomputedDataForAncestor( ancestorState); | |
| 65 const ClipPaintPropertyNode* clipNode = localState.clip; | |
| 66 Vector<const ClipPaintPropertyNode*> intermediateNodes; | |
| 67 FloatRect clip(LayoutRect::infiniteIntRect()); | |
| 68 | |
| 69 bool found = false; | |
| 70 // Iterate over the path from localState.clip to ancestorState.clip. Stop if we've found a memoized (precomputed) clip | |
| 71 // for any particular node. | |
| 72 while (clipNode) { | |
| 73 auto it = precomputedData->toAncestorClipRects.find(clipNode); | |
|
wkorman
2016/06/22 23:33:32
There should only be zero or one, right? Can we us
chrishtr
2016/06/23 00:18:26
get returns a temporary according the compiler, an
| |
| 74 if (it != precomputedData->toAncestorClipRects.end()) { | |
| 75 clip = it->value; | |
| 76 found = true; | |
| 77 break; | |
| 78 } | |
| 79 intermediateNodes.append(clipNode); | |
| 80 | |
| 81 if (clipNode == ancestorState.clip) | |
| 82 break; | |
| 83 | |
| 84 clipNode = clipNode->parent(); | |
| 85 } | |
| 86 // It's illegal to ask for a local-to-ancestor clip when the ancestor is not an ancestor. | |
| 87 DCHECK(clipNode == ancestorState.clip || found); | |
| 88 | |
| 89 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing clip rects as we go. | |
| 90 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); + +it) { | |
| 91 if ((*it) != ancestorState.clip) { | |
| 92 const TransformationMatrix transformMatrix = LocalToAncestorMatrix(( *it)->localTransformSpace(), ancestorState); | |
| 93 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rec t()); | |
| 94 clip.intersect(mappedRect); | |
| 95 } | |
| 96 | |
| 97 precomputedData->toAncestorClipRects.set(*it, clip); | |
| 98 } | |
| 99 | |
| 100 return precomputedData->toAncestorClipRects.find(localState.clip)->value; | |
| 101 } | |
| 102 | |
| 103 const TransformationMatrix GeometryMapper::LocalToAncestorMatrix( | |
| 104 const TransformPaintPropertyNode* localTransformNode, | |
| 105 const PropertyTreeState& ancestorState) { | |
|
Xianzhu
2016/06/22 23:20:30
Return a reference?
| |
| 106 PrecomputedDataForAncestor* precomputedData = GetPrecomputedDataForAncestor( ancestorState); | |
| 107 | |
| 108 const TransformPaintPropertyNode* transformNode = localTransformNode; | |
| 109 Vector<const TransformPaintPropertyNode*> intermediateNodes; | |
| 110 TransformationMatrix transformMatrix; | |
| 111 | |
| 112 bool found = false; | |
| 113 // Iterate over the path from localTransformNode to ancestorState.transform. Stop if we've found a memoized (precomputed) transform | |
| 114 // for any particular node. | |
| 115 while (transformNode) { | |
| 116 auto it = precomputedData->toAncestorTransforms.find(transformNode); | |
| 117 if (it != precomputedData->toAncestorTransforms.end()) { | |
| 118 transformMatrix = it->value; | |
| 119 found = true; | |
| 120 break; | |
| 121 } | |
| 122 | |
| 123 intermediateNodes.append(transformNode); | |
| 124 | |
| 125 if (transformNode == ancestorState.transform) | |
| 126 break; | |
| 127 | |
| 128 transformNode = transformNode->parent(); | |
| 129 } | |
| 130 // It's illegal to ask for a local-to-ancestor matrix when the ancestor is n ot an ancestor. | |
| 131 DCHECK(transformNode == ancestorState.transform || found); | |
| 132 | |
| 133 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing transforms as we go. | |
| 134 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); i t++) { | |
| 135 if ((*it) != ancestorState.transform) { | |
| 136 TransformationMatrix localTransformMatrix = (*it)->matrix(); | |
| 137 localTransformMatrix.applyTransformOrigin((*it)->origin()); | |
| 138 transformMatrix = localTransformMatrix * transformMatrix; | |
| 139 } | |
| 140 | |
| 141 precomputedData->toAncestorTransforms.set(*it, transformMatrix); | |
| 142 } | |
| 143 return precomputedData->toAncestorTransforms.find(localTransformNode)->value ; | |
| 144 } | |
| 145 | |
| 146 } // namespace blink | |
| OLD | NEW |