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

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: - Created 4 years, 4 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
44 // Assume that the clip of destinationState is an ancestor of the clip of so urceState
45 // and is under the space of lcaTransform. Otherwise localToAncestorClipRect () will fail.
46 PropertyTreeState lcaState = destinationState;
47 lcaState.transform = lcaTransform;
48
49 const auto clipRect = localToAncestorClipRect(sourceState, lcaState, success );
50 if (!success)
51 return rect;
52
53 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success) ;
54 DCHECK(success);
55 result.intersect(clipRect);
56
57 const TransformationMatrix& destinationToLca = localToAncestorMatrix(destina tionState.transform.get(), lcaState, success);
58 DCHECK(success);
59 if (destinationToLca.isInvertible()) {
60 success = true;
61 return destinationToLca.inverse().mapRect(result);
62 }
63 success = false;
64 return rect;
65 }
66
36 FloatRect GeometryMapper::slowMapRectToDestinationSpace(const FloatRect& rect, 67 FloatRect GeometryMapper::slowMapRectToDestinationSpace(const FloatRect& rect,
37 const PropertyTreeState& sourceState, 68 const PropertyTreeState& sourceState,
38 const PropertyTreeState& destinationState, 69 const PropertyTreeState& destinationState,
39 bool& success) 70 bool& success)
40 { 71 {
41 const TransformPaintPropertyNode* lcaTransform = propertyTreeNearestCommonAn cestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState .transform.get()); 72 const TransformPaintPropertyNode* lcaTransform = propertyTreeNearestCommonAn cestor<TransformPaintPropertyNode>(sourceState.transform.get(), destinationState .transform.get());
42 DCHECK(lcaTransform); 73 DCHECK(lcaTransform);
43 PropertyTreeState lcaState = sourceState; 74 PropertyTreeState lcaState = sourceState;
44 lcaState.transform = lcaTransform; 75 lcaState.transform = lcaTransform;
45 76
46 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success) ; 77 FloatRect result = localToAncestorRect(rect, sourceState, lcaState, success) ;
47 DCHECK(success); 78 DCHECK(success);
48 79
49 const TransformationMatrix& destinationToLca = localToAncestorMatrix(destina tionState.transform.get(), lcaState, success); 80 const TransformationMatrix& destinationToLca = localToAncestorMatrix(destina tionState.transform.get(), lcaState, success);
50 DCHECK(success); 81 DCHECK(success);
51 if (destinationToLca.isInvertible()) { 82 if (destinationToLca.isInvertible()) {
52 success = true; 83 success = true;
53 return destinationToLca.inverse().mapRect(result); 84 return destinationToLca.inverse().mapRect(result);
54 } 85 }
55 success = false; 86 success = false;
56 return rect; 87 return rect;
57 } 88 }
58 89
59 FloatRect GeometryMapper::localToVisualRectInAncestorSpace( 90 FloatRect GeometryMapper::localToVisualRectInAncestorSpace(
60 const FloatRect& rect, 91 const FloatRect& rect,
61 const PropertyTreeState& localState, 92 const PropertyTreeState& localState,
62 const PropertyTreeState& ancestorState, bool& success) 93 const PropertyTreeState& ancestorState, bool& success)
63 { 94 {
64 const auto transformMatrix = localToAncestorMatrix(localState.transform.get( ), ancestorState, success); 95 const auto& transformMatrix = localToAncestorMatrix(localState.transform.get (), ancestorState, success);
65 if (!success) 96 if (!success)
66 return rect; 97 return rect;
67 98
68 FloatRect mappedRect = transformMatrix.mapRect(rect); 99 FloatRect mappedRect = transformMatrix.mapRect(rect);
69 100
70 const auto clipRect = localToAncestorClipRect(localState, ancestorState); 101 const auto clipRect = localToAncestorClipRect(localState, ancestorState, suc cess);
102 DCHECK(success);
71 103
72 mappedRect.intersect(clipRect); 104 mappedRect.intersect(clipRect);
73 return mappedRect; 105 return mappedRect;
74 } 106 }
75 107
76 FloatRect GeometryMapper::localToAncestorRect( 108 FloatRect GeometryMapper::localToAncestorRect(
77 const FloatRect& rect, 109 const FloatRect& rect,
78 const PropertyTreeState& localState, 110 const PropertyTreeState& localState,
79 const PropertyTreeState& ancestorState, 111 const PropertyTreeState& ancestorState,
80 bool& success) 112 bool& success)
81 { 113 {
82 const auto transformMatrix = localToAncestorMatrix(localState.transform.get( ), ancestorState, success); 114 const auto& transformMatrix = localToAncestorMatrix(localState.transform.get (), ancestorState, success);
83 if (!success) 115 if (!success)
84 return rect; 116 return rect;
85 return transformMatrix.mapRect(rect); 117 return transformMatrix.mapRect(rect);
86 } 118 }
87 119
88 FloatRect GeometryMapper::ancestorToLocalRect( 120 FloatRect GeometryMapper::ancestorToLocalRect(
89 const FloatRect& rect, 121 const FloatRect& rect,
90 const PropertyTreeState& localState, 122 const PropertyTreeState& localState,
91 const PropertyTreeState& ancestorState, bool& success) 123 const PropertyTreeState& ancestorState, bool& success)
92 { 124 {
(...skipping 12 matching lines...) Expand all
105 } 137 }
106 138
107 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(const PropertyTreeState& ancestorState) 139 PrecomputedDataForAncestor& GeometryMapper::getPrecomputedDataForAncestor(const PropertyTreeState& ancestorState)
108 { 140 {
109 auto addResult = m_data.add(ancestorState.transform.get(), nullptr); 141 auto addResult = m_data.add(ancestorState.transform.get(), nullptr);
110 if (addResult.isNewEntry) 142 if (addResult.isNewEntry)
111 addResult.storedValue->value = PrecomputedDataForAncestor::create(); 143 addResult.storedValue->value = PrecomputedDataForAncestor::create();
112 return *addResult.storedValue->value; 144 return *addResult.storedValue->value;
113 } 145 }
114 146
115 const FloatRect& GeometryMapper::localToAncestorClipRect( 147 FloatRect GeometryMapper::localToAncestorClipRect(
116 const PropertyTreeState& localState, 148 const PropertyTreeState& localState,
117 const PropertyTreeState& ancestorState) 149 const PropertyTreeState& ancestorState,
150 bool& success)
118 { 151 {
119 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState); 152 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState);
120 const ClipPaintPropertyNode* clipNode = localState.clip.get(); 153 const ClipPaintPropertyNode* clipNode = localState.clip.get();
121 Vector<const ClipPaintPropertyNode*> intermediateNodes; 154 Vector<const ClipPaintPropertyNode*> intermediateNodes;
122 FloatRect clip(LayoutRect::infiniteIntRect()); 155 FloatRect clip(LayoutRect::infiniteIntRect());
123 156
124 bool found = false; 157 bool found = false;
125 // Iterate over the path from localState.clip to ancestorState.clip. Stop if we've found a memoized (precomputed) clip 158 // Iterate over the path from localState.clip to ancestorState.clip. Stop if we've found a memoized (precomputed) clip
126 // for any particular node. 159 // for any particular node.
127 while (clipNode) { 160 while (clipNode) {
128 auto it = precomputedData.toAncestorClipRects.find(clipNode); 161 auto it = precomputedData.toAncestorClipRects.find(clipNode);
129 if (it != precomputedData.toAncestorClipRects.end()) { 162 if (it != precomputedData.toAncestorClipRects.end()) {
130 clip = it->value; 163 clip = it->value;
131 found = true; 164 found = true;
132 break; 165 break;
133 } 166 }
134 intermediateNodes.append(clipNode); 167 intermediateNodes.append(clipNode);
135 168
136 if (clipNode == ancestorState.clip) 169 if (clipNode == ancestorState.clip)
137 break; 170 break;
138 171
139 clipNode = clipNode->parent(); 172 clipNode = clipNode->parent();
140 } 173 }
141 // It's illegal to ask for a local-to-ancestor clip when the ancestor is not an ancestor. 174 if (clipNode != ancestorState.clip && !found) {
142 DCHECK(clipNode == ancestorState.clip || found); 175 success = false;
176 return clip;
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; 182 success = false;
148 const TransformationMatrix transformMatrix = localToAncestorMatrix(( *it)->localTransformSpace(), ancestorState, success); 183 const TransformationMatrix& transformMatrix = localToAncestorMatrix( (*it)->localTransformSpace(), ancestorState, success);
149 DCHECK(success); 184 if (!success)
185 return clip;
150 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rec t()); 186 FloatRect mappedRect = transformMatrix.mapRect((*it)->clipRect().rec t());
151 clip.intersect(mappedRect); 187 clip.intersect(mappedRect);
152 } 188 }
153 189
154 precomputedData.toAncestorClipRects.set(*it, clip); 190 precomputedData.toAncestorClipRects.set(*it, clip);
155 } 191 }
156 192
193 success = true;
157 return precomputedData.toAncestorClipRects.find(localState.clip.get())->valu e; 194 return precomputedData.toAncestorClipRects.find(localState.clip.get())->valu e;
158 } 195 }
159 196
160
161 const TransformationMatrix& GeometryMapper::localToAncestorMatrix( 197 const TransformationMatrix& GeometryMapper::localToAncestorMatrix(
162 const TransformPaintPropertyNode* localTransformNode, 198 const TransformPaintPropertyNode* localTransformNode,
163 const PropertyTreeState& ancestorState, bool& success) { 199 const PropertyTreeState& ancestorState, bool& success) {
164 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState); 200 PrecomputedDataForAncestor& precomputedData = getPrecomputedDataForAncestor( ancestorState);
165 201
166 const TransformPaintPropertyNode* transformNode = localTransformNode; 202 const TransformPaintPropertyNode* transformNode = localTransformNode;
167 Vector<const TransformPaintPropertyNode*> intermediateNodes; 203 Vector<const TransformPaintPropertyNode*> intermediateNodes;
168 TransformationMatrix transformMatrix; 204 TransformationMatrix transformMatrix;
169 205
170 bool found = false; 206 bool found = false;
(...skipping 27 matching lines...) Expand all
198 transformMatrix = transformMatrix * localTransformMatrix; 234 transformMatrix = transformMatrix * localTransformMatrix;
199 } 235 }
200 236
201 precomputedData.toAncestorTransforms.set(*it, transformMatrix); 237 precomputedData.toAncestorTransforms.set(*it, transformMatrix);
202 } 238 }
203 success = true; 239 success = true;
204 return precomputedData.toAncestorTransforms.find(localTransformNode)->value; 240 return precomputedData.toAncestorTransforms.find(localTransformNode)->value;
205 } 241 }
206 242
207 } // namespace blink 243 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698