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

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

Issue 2268773002: Support css clip on fixed-position GeometryMapper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Support css clip on fixed-position GeometryMapper Created 4 years, 3 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::mapToVisualRectInDestinationSpace(const FloatRect& rec t, 14 FloatRect GeometryMapper::mapToVisualRectInDestinationSpace(const FloatRect& rec t,
15 const PropertyTreeState& sourceState, 15 const PropertyTreeState& sourceState,
16 const PropertyTreeState& destinationState, 16 const PropertyTreeState& destinationState,
17 bool& success) 17 bool& success)
18 { 18 {
19 FloatRect result = localToVisualRectInAncestorSpace(rect, sourceState, desti nationState, success); 19 FloatRect result = localToVisualRectInAncestorSpace(rect, sourceState, desti nationState, success);
20 if (success) 20 if (success)
21 return result; 21 return result;
22 return slowMapRectToDestinationSpace(rect, sourceState, destinationState, su ccess); 22 return slowMapToVisualRectInDestinationSpace(rect, sourceState, destinationS tate, success);
23 } 23 }
24 24
25 FloatRect GeometryMapper::mapRectToDestinationSpace(const FloatRect& rect, 25 FloatRect GeometryMapper::mapRectToDestinationSpace(const FloatRect& rect,
26 const PropertyTreeState& sourceState, 26 const PropertyTreeState& sourceState,
27 const PropertyTreeState& destinationState, 27 const PropertyTreeState& destinationState,
28 bool& success) 28 bool& success)
29 { 29 {
30 FloatRect result = localToAncestorRect(rect, sourceState, destinationState, success); 30 FloatRect result = localToAncestorRect(rect, sourceState, destinationState, success);
31 if (success) 31 if (success)
32 return result; 32 return result;
33 return slowMapRectToDestinationSpace(rect, sourceState, destinationState, su ccess); 33 return slowMapRectToDestinationSpace(rect, sourceState, destinationState, su ccess);
34 } 34 }
35 35
36 FloatRect GeometryMapper::slowMapToVisualRectInDestinationSpace(const FloatRect& rect,
37 const PropertyTreeState& sourceState,
38 const PropertyTreeState& destinationState,
39 bool& success)
40 {
41 const TransformPaintPropertyNode* lcaTransform = propertyTreeNearestCommonAn cestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState .transform.get());
42 DCHECK(lcaTransform);
43 PropertyTreeState lcaState = sourceState;
44 lcaState.transform = lcaTransform;
45
46 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success) ;
47 DCHECK(success);
48
49 // It's a failure if the clip of destinationState is not an ancestor of the clip of sourceState,
50 // because otherwise we can't undo the clips from the common ancestor to des tinationState.
51 const auto clipRect = localToAncestorClipRect(sourceState, destinationState, success);
52 if (!success)
53 return result;
54 result.intersect(clipRect);
55
56 const TransformationMatrix& destinationToLca = localToAncestorMatrix(destina tionState.transform.get(), lcaState, success);
57 DCHECK(success);
58 if (destinationToLca.isInvertible()) {
59 success = true;
60 return destinationToLca.inverse().mapRect(result);
61 }
62 success = false;
63 return rect;
64 }
65
36 FloatRect GeometryMapper::slowMapRectToDestinationSpace(const FloatRect& rect, 66 FloatRect GeometryMapper::slowMapRectToDestinationSpace(const FloatRect& rect,
37 const PropertyTreeState& sourceState, 67 const PropertyTreeState& sourceState,
38 const PropertyTreeState& destinationState, 68 const PropertyTreeState& destinationState,
39 bool& success) 69 bool& success)
40 { 70 {
41 const TransformPaintPropertyNode* lcaTransform = propertyTreeNearestCommonAn cestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState .transform.get()); 71 const TransformPaintPropertyNode* lcaTransform = propertyTreeNearestCommonAn cestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState .transform.get());
42 DCHECK(lcaTransform); 72 DCHECK(lcaTransform);
43 PropertyTreeState lcaState = sourceState; 73 PropertyTreeState lcaState = sourceState;
44 lcaState.transform = lcaTransform; 74 lcaState.transform = lcaTransform;
45 75
46 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success) ; 76 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success) ;
47 DCHECK(success); 77 DCHECK(success);
48 78
49 const TransformationMatrix& destinationToLca = localToAncestorMatrix(destina tionState.transform.get(), lcaState, success); 79 const TransformationMatrix& destinationToLca = localToAncestorMatrix(destina tionState.transform.get(), lcaState, success);
50 DCHECK(success); 80 DCHECK(success);
51 if (destinationToLca.isInvertible()) { 81 if (destinationToLca.isInvertible()) {
52 success = true; 82 success = true;
53 return destinationToLca.inverse().mapRect(result); 83 return destinationToLca.inverse().mapRect(result);
54 } 84 }
55 success = false; 85 success = false;
56 return rect; 86 return rect;
57 } 87 }
58 88
59 FloatRect GeometryMapper::localToVisualRectInAncestorSpace( 89 FloatRect GeometryMapper::localToVisualRectInAncestorSpace(
60 const FloatRect& rect, 90 const FloatRect& rect,
61 const PropertyTreeState& localState, 91 const PropertyTreeState& localState,
62 const PropertyTreeState& ancestorState, bool& success) 92 const PropertyTreeState& ancestorState, bool& success)
63 { 93 {
64 const auto transformMatrix = localToAncestorMatrix(localState.transform.get( ), ancestorState, success); 94 const auto& transformMatrix = localToAncestorMatrix(localState.transform.get (), ancestorState, success);
65 if (!success) 95 if (!success)
66 return rect; 96 return rect;
67 97
68 FloatRect mappedRect = transformMatrix.mapRect(rect); 98 FloatRect mappedRect = transformMatrix.mapRect(rect);
69 99
70 const auto clipRect = localToAncestorClipRect(localState, ancestorState); 100 const auto clipRect = localToAncestorClipRect(localState, ancestorState, suc cess);
101 DCHECK(success);
71 102
72 mappedRect.intersect(clipRect); 103 mappedRect.intersect(clipRect);
73 return mappedRect; 104 return mappedRect;
74 } 105 }
75 106
76 FloatRect GeometryMapper::localToAncestorRect( 107 FloatRect GeometryMapper::localToAncestorRect(
77 const FloatRect& rect, 108 const FloatRect& rect,
78 const PropertyTreeState& localState, 109 const PropertyTreeState& localState,
79 const PropertyTreeState& ancestorState, 110 const PropertyTreeState& ancestorState,
80 bool& success) 111 bool& success)
81 { 112 {
82 const auto transformMatrix = localToAncestorMatrix(localState.transform.get( ), ancestorState, success); 113 const auto& transformMatrix = localToAncestorMatrix(localState.transform.get (), ancestorState, success);
83 if (!success) 114 if (!success)
84 return rect; 115 return rect;
85 return transformMatrix.mapRect(rect); 116 return transformMatrix.mapRect(rect);
86 } 117 }
87 118
88 FloatRect GeometryMapper::ancestorToLocalRect( 119 FloatRect GeometryMapper::ancestorToLocalRect(
89 const FloatRect& rect, 120 const FloatRect& rect,
90 const PropertyTreeState& localState, 121 const PropertyTreeState& localState,
91 const PropertyTreeState& ancestorState, bool& success) 122 const PropertyTreeState& ancestorState, bool& success)
92 { 123 {
(...skipping 12 matching lines...) Expand all
105 } 136 }
106 137
107 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(const PropertyTreeState& ancestorState) 138 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(const PropertyTreeState& ancestorState)
108 { 139 {
109 auto addResult = m_data.add(ancestorState.transform.get(), nullptr); 140 auto addResult = m_data.add(ancestorState.transform.get(), nullptr);
110 if (addResult.isNewEntry) 141 if (addResult.isNewEntry)
111 addResult.storedValue->value = PrecomputedDataForAncestor::create(); 142 addResult.storedValue->value = PrecomputedDataForAncestor::create();
112 return *addResult.storedValue->value; 143 return *addResult.storedValue->value;
113 } 144 }
114 145
115 const FloatRect& GeometryMapper::localToAncestorClipRect( 146 FloatRect GeometryMapper::localToAncestorClipRect(
116 const PropertyTreeState& localState, 147 const PropertyTreeState& localState,
117 const PropertyTreeState& ancestorState) 148 const PropertyTreeState& ancestorState,
149 bool& success)
118 { 150 {
119 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState); 151 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState);
120 const ClipPaintPropertyNode* clipNode = localState.clip.get(); 152 const ClipPaintPropertyNode* clipNode = localState.clip.get();
121 Vector<const ClipPaintPropertyNode*> intermediateNodes; 153 Vector<const ClipPaintPropertyNode*> intermediateNodes;
122 FloatRect clip(LayoutRect::infiniteIntRect()); 154 FloatRect clip(LayoutRect::infiniteIntRect());
123 155
124 bool found = false; 156 bool found = false;
125 // Iterate over the path from localState.clip to ancestorState.clip. Stop if we've found a memoized (precomputed) clip 157 // Iterate over the path from localState.clip to ancestorState.clip. Stop if we've found a memoized (precomputed) clip
126 // for any particular node. 158 // for any particular node.
127 while (clipNode) { 159 while (clipNode) {
128 auto it = precomputedData.toAncestorClipRects.find(clipNode); 160 auto it = precomputedData.toAncestorClipRects.find(clipNode);
129 if (it != precomputedData.toAncestorClipRects.end()) { 161 if (it != precomputedData.toAncestorClipRects.end()) {
130 clip = it->value; 162 clip = it->value;
131 found = true; 163 found = true;
132 break; 164 break;
133 } 165 }
134 intermediateNodes.append(clipNode); 166 intermediateNodes.append(clipNode);
135 167
136 if (clipNode == ancestorState.clip) 168 if (clipNode == ancestorState.clip)
137 break; 169 break;
138 170
139 clipNode = clipNode->parent(); 171 clipNode = clipNode->parent();
140 } 172 }
141 // It's illegal to ask for a local-to-ancestor clip when the ancestor is not an ancestor. 173 // 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.
142 DCHECK(clipNode == ancestorState.clip || found); 174 if (clipNode != ancestorState.clip && !found) {
175 success = false;
176 return LayoutRect::infiniteIntRect();
177 }
143 178
144 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing clip rects as we go. 179 // Iterate down from the top intermediate node found in the previous loop, c omputing and memoizing clip rects as we go.
145 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); + +it) { 180 for (auto it = intermediateNodes.rbegin(); it != intermediateNodes.rend(); + +it) {
146 if ((*it) != ancestorState.clip) { 181 if ((*it) != ancestorState.clip) {
147 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
148 const TransformationMatrix transformMatrix = localToAncestorMatrix(( *it)->localTransformSpace(), ancestorState, success); 182 const TransformationMatrix transformMatrix = localToAncestorMatrix(( *it)->localTransformSpace(), ancestorState, success);
149 DCHECK(success); 183 DCHECK(success);
150 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rec t()); 184 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rec t());
151 clip.intersect(mappedRect); 185 clip.intersect(mappedRect);
152 } 186 }
153 187
154 precomputedData.toAncestorClipRects.set(*it, clip); 188 precomputedData.toAncestorClipRects.set(*it, clip);
155 } 189 }
156 190
157 return precomputedData.toAncestorClipRects.find(localState.clip.get())->valu e; 191 return precomputedData.toAncestorClipRects.find(localState.clip.get())->valu e;
158 } 192 }
159 193
160
161 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 194 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
162 const TransformPaintPropertyNode* localTransformNode, 195 const TransformPaintPropertyNode* localTransformNode,
163 const PropertyTreeState& ancestorState, bool& success) { 196 const PropertyTreeState& ancestorState, bool& success) {
164 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState); 197 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState);
165 198
166 const TransformPaintPropertyNode* transformNode = localTransformNode; 199 const TransformPaintPropertyNode* transformNode = localTransformNode;
167 Vector<const TransformPaintPropertyNode*> intermediateNodes; 200 Vector<const TransformPaintPropertyNode*> intermediateNodes;
168 TransformationMatrix transformMatrix; 201 TransformationMatrix transformMatrix;
169 202
170 bool found = false; 203 bool found = false;
(...skipping 27 matching lines...) Expand all
198 transformMatrix = transformMatrix * localTransformMatrix; 231 transformMatrix = transformMatrix * localTransformMatrix;
199 } 232 }
200 233
201 precomputedData.toAncestorTransforms.set(*it, transformMatrix); 234 precomputedData.toAncestorTransforms.set(*it, transformMatrix);
202 } 235 }
203 success = true; 236 success = true;
204 return precomputedData.toAncestorTransforms.find(localTransformNode)->value; 237 return precomputedData.toAncestorTransforms.find(localTransformNode)->value;
205 } 238 }
206 239
207 } // namespace blink 240 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698