Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(23)

Side by Side Diff: third_party/WebKit/Source/platform/graphics/paint/GeometryMapper.cpp

Issue 2105273004: GeometryMapper: Support computing visual rects in spaces that are not direct ancestors. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: none Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "platform/graphics/paint/GeometryMapper.h" 5 #include "platform/graphics/paint/GeometryMapper.h"
6 6
7 #include "platform/geometry/LayoutRect.h" 7 #include "platform/geometry/LayoutRect.h"
8 #include "platform/graphics/paint/ClipPaintPropertyNode.h" 8 #include "platform/graphics/paint/ClipPaintPropertyNode.h"
9 #include "platform/graphics/paint/EffectPaintPropertyNode.h" 9 #include "platform/graphics/paint/EffectPaintPropertyNode.h"
10 #include "platform/graphics/paint/TransformPaintPropertyNode.h" 10 #include "platform/graphics/paint/TransformPaintPropertyNode.h"
11 11
12 namespace blink { 12 namespace blink {
13 13
14 FloatRect GeometryMapper::LocalToVisualRectInAncestorSpace( 14 FloatRect GeometryMapper::mapToVisualRectInDestinationSpace(const FloatRect& rec t,
15 const PropertyTreeState& sourceState,
16 const PropertyTreeState& destinationState,
17 bool& success)
18 {
19 FloatRect result = localToVisualRectInAncestorSpace(rect, sourceState, desti nationState, success);
20 if (success)
21 return result;
22
23 // TODO(chrishtr): fixed const-ness here.
24 RefPtr<TransformPaintPropertyNode> lcaTransform = const_cast<TransformPaintP ropertyNode*>(propertyTreeNearestCommonAncestor<TransformPaintPropertyNode>(sour ceState.transform.get(), destinationState.transform.get()));
25 DCHECK(lcaTransform.get());
26 PropertyTreeState lcaState = sourceState;
27 lcaState.transform = lcaTransform;
28
29 result = localToAncestorMatrix(sourceState.transform.get(), lcaState, succes s).mapRect(rect);
30 DCHECK(success);
31
32 const TransformationMatrix& destinationToLca = localToAncestorMatrix(destina tionState.transform.get(), lcaState, success);
33 DCHECK(success);
34 if (destinationToLca.isInvertible()) {
35 success = true;
36 return destinationToLca.inverse().mapRect(result);
37 }
38 success = false;
39 return rect;
40 }
41
42 FloatRect GeometryMapper::localToVisualRectInAncestorSpace(
15 const FloatRect& rect, 43 const FloatRect& rect,
16 const PropertyTreeState& localState, 44 const PropertyTreeState& localState,
17 const PropertyTreeState& ancestorState) 45 const PropertyTreeState& ancestorState, bool& success)
18 { 46 {
19 const auto transformMatrix = LocalToAncestorMatrix(localState.transform, anc estorState); 47 const auto transformMatrix = localToAncestorMatrix(localState.transform.get( ), ancestorState, success);
48 if (!success)
49 return rect;
50
20 FloatRect mappedRect = transformMatrix.mapRect(rect); 51 FloatRect mappedRect = transformMatrix.mapRect(rect);
21 52
22 const auto clipRect = LocalToAncestorClipRect(localState, ancestorState); 53 const auto clipRect = localToAncestorClipRect(localState, ancestorState);
23 54
24 mappedRect.intersect(clipRect); 55 mappedRect.intersect(clipRect);
25 return mappedRect; 56 return mappedRect;
26 } 57 }
27 58
28 FloatRect GeometryMapper::LocalToAncestorRect( 59 FloatRect GeometryMapper::localToAncestorRect(
29 const FloatRect& rect, 60 const FloatRect& rect,
30 const PropertyTreeState& localState, 61 const PropertyTreeState& localState,
31 const PropertyTreeState& ancestorState) 62 const PropertyTreeState& ancestorState,
63 bool& success)
32 { 64 {
33 const auto transformMatrix = LocalToAncestorMatrix(localState.transform, anc estorState); 65 const auto transformMatrix = localToAncestorMatrix(localState.transform.get( ), ancestorState, success);
66 if (!success)
67 return rect;
34 return transformMatrix.mapRect(rect); 68 return transformMatrix.mapRect(rect);
35 } 69 }
36 70
37 FloatRect GeometryMapper::AncestorToLocalRect( 71 FloatRect GeometryMapper::ancestorToLocalRect(
38 const FloatRect& rect, 72 const FloatRect& rect,
39 const PropertyTreeState& localState, 73 const PropertyTreeState& localState,
40 const PropertyTreeState& ancestorState, bool* success) 74 const PropertyTreeState& ancestorState, bool& success)
41 { 75 {
42 const auto& transformMatrix = LocalToAncestorMatrix(localState.transform, an cestorState); 76 const auto& transformMatrix = localToAncestorMatrix(localState.transform.get (), ancestorState, success);
77 if (!success)
78 return rect;
79
43 if (!transformMatrix.isInvertible()) { 80 if (!transformMatrix.isInvertible()) {
44 *success = false; 81 success = false;
45 return FloatRect(); 82 return rect;
46 } 83 }
47 *success = true; 84 success = true;
48 85
49 // TODO(chrishtr): Cache the inverse? 86 // TODO(chrishtr): Cache the inverse?
50 return transformMatrix.inverse().mapRect(rect); 87 return transformMatrix.inverse().mapRect(rect);
51 } 88 }
52 89
53 PrecomputedDataForAncestor& GeometryMapper::GetPrecomputedDataForAncestor(const PropertyTreeState& ancestorState) 90 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(const PropertyTreeState& ancestorState)
54 { 91 {
55 auto addResult = m_data.add(ancestorState.transform, nullptr); 92 auto addResult = m_data.add(ancestorState.transform.get(), nullptr);
56 if (addResult.isNewEntry) 93 if (addResult.isNewEntry)
57 addResult.storedValue->value = PrecomputedDataForAncestor::create(); 94 addResult.storedValue->value = PrecomputedDataForAncestor::create();
58 return *addResult.storedValue->value; 95 return *addResult.storedValue->value;
59 } 96 }
60 97
61 const FloatRect& GeometryMapper::LocalToAncestorClipRect( 98 const FloatRect& GeometryMapper::localToAncestorClipRect(
62 const PropertyTreeState& localState, 99 const PropertyTreeState& localState,
63 const PropertyTreeState& ancestorState) 100 const PropertyTreeState& ancestorState)
64 { 101 {
65 PrecomputedDataForAncestor& precomputedData = GetPrecomputedDataForAncestor( ancestorState); 102 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState);
66 const ClipPaintPropertyNode* clipNode = localState.clip; 103 const ClipPaintPropertyNode* clipNode = localState.clip.get();
67 Vector<const ClipPaintPropertyNode*> intermediateNodes; 104 Vector<const ClipPaintPropertyNode*> intermediateNodes;
68 FloatRect clip(LayoutRect::infiniteIntRect()); 105 FloatRect clip(LayoutRect::infiniteIntRect());
69 106
70 bool found = false; 107 bool found = false;
71 // Iterate over the path from localState.clip to ancestorState.clip. Stop if we've found a memoized (precomputed) clip 108 // Iterate over the path from localState.clip to ancestorState.clip. Stop if we've found a memoized (precomputed) clip
72 // for any particular node. 109 // for any particular node.
73 while (clipNode) { 110 while (clipNode) {
74 auto it = precomputedData.toAncestorClipRects.find(clipNode); 111 auto it = precomputedData.toAncestorClipRects.find(clipNode);
75 if (it != precomputedData.toAncestorClipRects.end()) { 112 if (it != precomputedData.toAncestorClipRects.end()) {
76 clip = it->value; 113 clip = it->value;
77 found = true; 114 found = true;
78 break; 115 break;
79 } 116 }
80 intermediateNodes.append(clipNode); 117 intermediateNodes.append(clipNode);
81 118
82 if (clipNode == ancestorState.clip) 119 if (clipNode == ancestorState.clip)
83 break; 120 break;
84 121
85 clipNode = clipNode->parent(); 122 clipNode = clipNode->parent();
86 } 123 }
87 // It's illegal to ask for a local-to-ancestor clip when the ancestor is not an ancestor. 124 // It's illegal to ask for a local-to-ancestor clip when the ancestor is not an ancestor.
88 DCHECK(clipNode == ancestorState.clip || found); 125 DCHECK(clipNode == ancestorState.clip || found);
89 126
90 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing clip rects as we go. 127 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing clip rects as we go.
91 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); + +it) { 128 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); + +it) {
92 if ((*it) != ancestorState.clip) { 129 if ((*it) != ancestorState.clip) {
93 const TransformationMatrix transformMatrix = LocalToAncestorMatrix(( *it)->localTransformSpace(), ancestorState); 130 bool success = false;
131 const TransformationMatrix transformMatrix = localToAncestorMatrix(( *it)->localTransformSpace(), ancestorState, success);
132 DCHECK(success);
94 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rec t()); 133 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rec t());
95 clip.intersect(mappedRect); 134 clip.intersect(mappedRect);
96 } 135 }
97 136
98 precomputedData.toAncestorClipRects.set(*it, clip); 137 precomputedData.toAncestorClipRects.set(*it, clip);
99 } 138 }
100 139
101 return precomputedData.toAncestorClipRects.find(localState.clip)->value; 140 return precomputedData.toAncestorClipRects.find(localState.clip.get())->valu e;
102 } 141 }
103 142
104 const TransformationMatrix& GeometryMapper::LocalToAncestorMatrix( 143
144 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
105 const TransformPaintPropertyNode* localTransformNode, 145 const TransformPaintPropertyNode* localTransformNode,
106 const PropertyTreeState& ancestorState) { 146 const PropertyTreeState& ancestorState, bool& success) {
107 PrecomputedDataForAncestor& precomputedData = GetPrecomputedDataForAncestor( ancestorState); 147 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState);
108 148
109 const TransformPaintPropertyNode* transformNode = localTransformNode; 149 const TransformPaintPropertyNode* transformNode = localTransformNode;
110 Vector<const TransformPaintPropertyNode*> intermediateNodes; 150 Vector<const TransformPaintPropertyNode*> intermediateNodes;
111 TransformationMatrix transformMatrix; 151 TransformationMatrix transformMatrix;
112 152
113 bool found = false; 153 bool found = false;
114 // Iterate over the path from localTransformNode to ancestorState.transform. Stop if we've found a memoized (precomputed) transform 154 // Iterate over the path from localTransformNode to ancestorState.transform. Stop if we've found a memoized (precomputed) transform
115 // for any particular node. 155 // for any particular node.
116 while (transformNode) { 156 while (transformNode) {
117 auto it = precomputedData.toAncestorTransforms.find(transformNode); 157 auto it = precomputedData.toAncestorTransforms.find(transformNode);
118 if (it != precomputedData.toAncestorTransforms.end()) { 158 if (it != precomputedData.toAncestorTransforms.end()) {
119 transformMatrix = it->value; 159 transformMatrix = it->value;
120 found = true; 160 found = true;
121 break; 161 break;
122 } 162 }
123 163
124 intermediateNodes.append(transformNode); 164 intermediateNodes.append(transformNode);
125 165
126 if (transformNode == ancestorState.transform) 166 if (transformNode == ancestorState.transform)
127 break; 167 break;
128 168
129 transformNode = transformNode->parent(); 169 transformNode = transformNode->parent();
130 } 170 }
131 // It's illegal to ask for a local-to-ancestor matrix when the ancestor is n ot an ancestor. 171 if (!found && transformNode != ancestorState.transform) {
132 DCHECK(transformNode == ancestorState.transform || found); 172 success = false;
173 return m_identity;
174 }
133 175
134 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing transforms as we go. 176 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing transforms as we go.
135 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); i t++) { 177 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); i t++) {
136 if ((*it) != ancestorState.transform) { 178 if ((*it) != ancestorState.transform) {
137 TransformationMatrix localTransformMatrix = (*it)->matrix(); 179 TransformationMatrix localTransformMatrix = (*it)->matrix();
138 localTransformMatrix.applyTransformOrigin((*it)->origin()); 180 localTransformMatrix.applyTransformOrigin((*it)->origin());
139 transformMatrix = localTransformMatrix * transformMatrix; 181 transformMatrix = localTransformMatrix * transformMatrix;
140 } 182 }
141 183
142 precomputedData.toAncestorTransforms.set(*it, transformMatrix); 184 precomputedData.toAncestorTransforms.set(*it, transformMatrix);
143 } 185 }
186 success = true;
144 return precomputedData.toAncestorTransforms.find(localTransformNode)->value; 187 return precomputedData.toAncestorTransforms.find(localTransformNode)->value;
145 } 188 }
146 189
147 } // namespace blink 190 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698