OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights |
3 * reserved. | 3 * reserved. |
4 * | 4 * |
5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
6 * | 6 * |
7 * Other contributors: | 7 * Other contributors: |
8 * Robert O'Callahan <roc+@cs.cmu.edu> | 8 * Robert O'Callahan <roc+@cs.cmu.edu> |
9 * David Baron <dbaron@fas.harvard.edu> | 9 * David Baron <dbaron@fas.harvard.edu> |
10 * Christian Biesinger <cbiesinger@web.de> | 10 * Christian Biesinger <cbiesinger@web.de> |
(...skipping 30 matching lines...) Expand all Loading... |
41 * If you do not delete the provisions above, a recipient may use your | 41 * If you do not delete the provisions above, a recipient may use your |
42 * version of this file under any of the LGPL, the MPL or the GPL. | 42 * version of this file under any of the LGPL, the MPL or the GPL. |
43 */ | 43 */ |
44 | 44 |
45 #include "core/paint/PaintLayerClipper.h" | 45 #include "core/paint/PaintLayerClipper.h" |
46 | 46 |
47 #include "core/frame/FrameView.h" | 47 #include "core/frame/FrameView.h" |
48 #include "core/frame/Settings.h" | 48 #include "core/frame/Settings.h" |
49 #include "core/layout/LayoutView.h" | 49 #include "core/layout/LayoutView.h" |
50 #include "core/layout/svg/LayoutSVGRoot.h" | 50 #include "core/layout/svg/LayoutSVGRoot.h" |
| 51 #include "core/paint/ObjectPaintProperties.h" |
51 #include "core/paint/PaintLayer.h" | 52 #include "core/paint/PaintLayer.h" |
| 53 #include "core/paint/PaintPropertyTreePrinter.h" |
52 | 54 |
53 namespace blink { | 55 namespace blink { |
54 | 56 |
55 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, | 57 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, |
56 ClipRects& clipRects) { | 58 ClipRects& clipRects) { |
57 EPosition position = layoutObject.styleRef().position(); | 59 EPosition position = layoutObject.styleRef().position(); |
58 // A fixed object is essentially the root of its containing block hierarchy, | 60 // A fixed object is essentially the root of its containing block hierarchy, |
59 // so when we encounter such an object, we reset our clip rects to the | 61 // so when we encounter such an object, we reset our clip rects to the |
60 // fixedClipRect. | 62 // fixedClipRect. |
61 if (position == FixedPosition) { | 63 if (position == FixedPosition) { |
(...skipping 15 matching lines...) Expand all Loading... |
77 (layoutObject.isSVGRoot() && | 79 (layoutObject.isSVGRoot() && |
78 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip())); | 80 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip())); |
79 LayoutView* view = layoutObject.view(); | 81 LayoutView* view = layoutObject.view(); |
80 DCHECK(view); | 82 DCHECK(view); |
81 if (clipRects.fixed() && context.rootLayer->layoutObject() == view) | 83 if (clipRects.fixed() && context.rootLayer->layoutObject() == view) |
82 offset -= toIntSize(view->frameView()->scrollPosition()); | 84 offset -= toIntSize(view->frameView()->scrollPosition()); |
83 if (layoutObject.hasOverflowClip() || | 85 if (layoutObject.hasOverflowClip() || |
84 (layoutObject.isSVGRoot() && | 86 (layoutObject.isSVGRoot() && |
85 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || | 87 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || |
86 (layoutObject.styleRef().containsPaint() && layoutObject.isBox())) { | 88 (layoutObject.styleRef().containsPaint() && layoutObject.isBox())) { |
87 ClipRect newOverflowClip = | 89 ClipRect newOverflowClip; |
| 90 newOverflowClip = |
88 toLayoutBox(layoutObject) | 91 toLayoutBox(layoutObject) |
89 .overflowClipRect(offset, context.overlayScrollbarClipBehavior); | 92 .overflowClipRect(offset, context.overlayScrollbarClipBehavior); |
90 newOverflowClip.setHasRadius(layoutObject.styleRef().hasBorderRadius()); | 93 newOverflowClip.setHasRadius(layoutObject.styleRef().hasBorderRadius()); |
91 clipRects.setOverflowClipRect( | 94 clipRects.setOverflowClipRect( |
92 intersection(newOverflowClip, clipRects.overflowClipRect())); | 95 intersection(newOverflowClip, clipRects.overflowClipRect())); |
93 if (layoutObject.isPositioned()) | 96 if (layoutObject.isPositioned()) |
94 clipRects.setPosClipRect( | 97 clipRects.setPosClipRect( |
95 intersection(newOverflowClip, clipRects.posClipRect())); | 98 intersection(newOverflowClip, clipRects.posClipRect())); |
96 if (layoutObject.isLayoutView()) | 99 if (layoutObject.isLayoutView()) |
97 clipRects.setFixedClipRect( | 100 clipRects.setFixedClipRect( |
(...skipping 10 matching lines...) Expand all Loading... |
108 clipRects.setPosClipRect( | 111 clipRects.setPosClipRect( |
109 intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss()); | 112 intersection(newClip, clipRects.posClipRect()).setIsClippedByClipCss()); |
110 clipRects.setOverflowClipRect( | 113 clipRects.setOverflowClipRect( |
111 intersection(newClip, clipRects.overflowClipRect()) | 114 intersection(newClip, clipRects.overflowClipRect()) |
112 .setIsClippedByClipCss()); | 115 .setIsClippedByClipCss()); |
113 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect()) | 116 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect()) |
114 .setIsClippedByClipCss()); | 117 .setIsClippedByClipCss()); |
115 } | 118 } |
116 } | 119 } |
117 | 120 |
| 121 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer, |
| 122 bool useGeometryMapper) |
| 123 : m_layer(layer), |
| 124 m_geometryMapper(useGeometryMapper ? new GeometryMapper : nullptr) {} |
| 125 |
118 ClipRects* PaintLayerClipper::clipRectsIfCached( | 126 ClipRects* PaintLayerClipper::clipRectsIfCached( |
119 const ClipRectsContext& context) const { | 127 const ClipRectsContext& context) const { |
120 DCHECK(context.usesCache()); | 128 DCHECK(context.usesCache()); |
121 if (!m_layer.clipRectsCache()) | 129 if (!m_layer.clipRectsCache()) |
122 return nullptr; | 130 return nullptr; |
123 ClipRectsCache::Entry& entry = | 131 ClipRectsCache::Entry& entry = |
124 m_layer.clipRectsCache()->get(context.cacheSlot()); | 132 m_layer.clipRectsCache()->get(context.cacheSlot()); |
125 // FIXME: We used to ASSERT that we always got a consistent root layer. | 133 // FIXME: We used to ASSERT that we always got a consistent root layer. |
126 // We should add a test that has an inconsistent root. See | 134 // We should add a test that has an inconsistent root. See |
127 // http://crbug.com/366118 for an example. | 135 // http://crbug.com/366118 for an example. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
164 // the cache. | 172 // the cache. |
165 ClipRects* parentClipRects = nullptr; | 173 ClipRects* parentClipRects = nullptr; |
166 if (context.rootLayer != &m_layer && m_layer.parent()) | 174 if (context.rootLayer != &m_layer && m_layer.parent()) |
167 parentClipRects = &m_layer.parent()->clipper().getClipRects(context); | 175 parentClipRects = &m_layer.parent()->clipper().getClipRects(context); |
168 RefPtr<ClipRects> clipRects = ClipRects::create(); | 176 RefPtr<ClipRects> clipRects = ClipRects::create(); |
169 calculateClipRects(context, *clipRects); | 177 calculateClipRects(context, *clipRects); |
170 return storeClipRectsInCache(context, parentClipRects, *clipRects); | 178 return storeClipRectsInCache(context, parentClipRects, *clipRects); |
171 } | 179 } |
172 | 180 |
173 void PaintLayerClipper::clearClipRectsIncludingDescendants() { | 181 void PaintLayerClipper::clearClipRectsIncludingDescendants() { |
| 182 if (m_geometryMapper) |
| 183 m_geometryMapper.reset(new GeometryMapper); |
174 m_layer.clearClipRectsCache(); | 184 m_layer.clearClipRectsCache(); |
175 | 185 |
176 for (PaintLayer* layer = m_layer.firstChild(); layer; | 186 for (PaintLayer* layer = m_layer.firstChild(); layer; |
177 layer = layer->nextSibling()) { | 187 layer = layer->nextSibling()) { |
178 layer->clipper().clearClipRectsIncludingDescendants(); | 188 layer->clipper().clearClipRectsIncludingDescendants(); |
179 } | 189 } |
180 } | 190 } |
181 | 191 |
182 void PaintLayerClipper::clearClipRectsIncludingDescendants( | 192 void PaintLayerClipper::clearClipRectsIncludingDescendants( |
183 ClipRectsCacheSlot cacheSlot) { | 193 ClipRectsCacheSlot cacheSlot) { |
| 194 if (m_geometryMapper) |
| 195 m_geometryMapper.reset(new GeometryMapper); |
| 196 |
184 if (ClipRectsCache* cache = m_layer.clipRectsCache()) | 197 if (ClipRectsCache* cache = m_layer.clipRectsCache()) |
185 cache->clear(cacheSlot); | 198 cache->clear(cacheSlot); |
186 | 199 |
187 for (PaintLayer* layer = m_layer.firstChild(); layer; | 200 for (PaintLayer* layer = m_layer.firstChild(); layer; |
188 layer = layer->nextSibling()) { | 201 layer = layer->nextSibling()) { |
189 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); | 202 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); |
190 } | 203 } |
191 } | 204 } |
192 | 205 |
193 LayoutRect PaintLayerClipper::localClipRect( | 206 LayoutRect PaintLayerClipper::localClipRect( |
194 const PaintLayer* clippingRootLayer) const { | 207 const PaintLayer* clippingRootLayer) const { |
| 208 ClipRectsContext context(clippingRootLayer, PaintingClipRects); |
| 209 if (m_geometryMapper) { |
| 210 ClipRect clipRect = applyOverflowClipToBackgroundRectWithGeometryMapper( |
| 211 context, clipRectWithGeometryMapper(context, false)); |
| 212 |
| 213 // The rect now needs to be transformed to the local space of this PaintLaye
r. |
| 214 bool success = false; |
| 215 FloatRect clippedRectInLocalSpace = |
| 216 m_geometryMapper->mapRectToDestinationSpace( |
| 217 FloatRect(clipRect.rect()), clippingRootLayer->layoutObject() |
| 218 ->objectPaintProperties() |
| 219 ->localBorderBoxProperties() |
| 220 ->propertyTreeState, |
| 221 m_layer.layoutObject() |
| 222 ->objectPaintProperties() |
| 223 ->localBorderBoxProperties() |
| 224 ->propertyTreeState, |
| 225 success); |
| 226 DCHECK(success); |
| 227 |
| 228 return LayoutRect(clippedRectInLocalSpace); |
| 229 } |
| 230 |
195 LayoutRect layerBounds; | 231 LayoutRect layerBounds; |
196 ClipRect backgroundRect, foregroundRect; | 232 ClipRect backgroundRect, foregroundRect; |
197 ClipRectsContext context(clippingRootLayer, PaintingClipRects); | |
198 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), | 233 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), |
199 layerBounds, backgroundRect, foregroundRect); | 234 layerBounds, backgroundRect, foregroundRect); |
200 | 235 |
201 LayoutRect clipRect = backgroundRect.rect(); | 236 LayoutRect clipRect = backgroundRect.rect(); |
202 // TODO(chrishtr): avoid converting to IntRect and back. | 237 // TODO(chrishtr): avoid converting to IntRect and back. |
203 if (clipRect == LayoutRect(LayoutRect::infiniteIntRect())) | 238 if (clipRect == LayoutRect(LayoutRect::infiniteIntRect())) |
204 return clipRect; | 239 return clipRect; |
205 | 240 |
206 LayoutPoint clippingRootOffset; | 241 LayoutPoint clippingRootOffset; |
207 m_layer.convertToLayerCoords(clippingRootLayer, clippingRootOffset); | 242 m_layer.convertToLayerCoords(clippingRootLayer, clippingRootOffset); |
208 clipRect.moveBy(-clippingRootOffset); | 243 clipRect.moveBy(-clippingRootOffset); |
209 | 244 |
210 return clipRect; | 245 return clipRect; |
211 } | 246 } |
212 | 247 |
| 248 #ifdef CHECK_CLIP_RECTS |
| 249 #define CHECK_RECTS_EQ(expected, actual) \ |
| 250 CHECK((expected.isEmpty() && actual.isEmpty()) || expected == actual) \ |
| 251 << "expected=" << expected.toString() << " actual=" << actual.toString() |
| 252 #endif |
| 253 |
| 254 void PaintLayerClipper::mapLocalToRootWithGeometryMapper( |
| 255 const ClipRectsContext& context, |
| 256 LayoutRect& layoutRect) const { |
| 257 DCHECK(m_geometryMapper); |
| 258 bool success; |
| 259 |
| 260 const ObjectPaintProperties::PropertyTreeStateWithOffset* |
| 261 layerBorderBoxProperties = m_layer.layoutObject() |
| 262 ->objectPaintProperties() |
| 263 ->localBorderBoxProperties(); |
| 264 FloatRect localRect(layoutRect); |
| 265 localRect.moveBy(FloatPoint(layerBorderBoxProperties->paintOffset)); |
| 266 |
| 267 layoutRect = LayoutRect(m_geometryMapper->mapRectToDestinationSpace( |
| 268 localRect, layerBorderBoxProperties->propertyTreeState, |
| 269 context.rootLayer->layoutObject() |
| 270 ->objectPaintProperties() |
| 271 ->localBorderBoxProperties() |
| 272 ->propertyTreeState, |
| 273 success)); |
| 274 DCHECK(success); |
| 275 } |
| 276 |
| 277 void PaintLayerClipper::calculateRectsWithGeometryMapper( |
| 278 const ClipRectsContext& context, |
| 279 const LayoutRect& paintDirtyRect, |
| 280 LayoutRect& layerBounds, |
| 281 ClipRect& backgroundRect, |
| 282 ClipRect& foregroundRect, |
| 283 const LayoutPoint* offsetFromRoot) const { |
| 284 backgroundRect = applyOverflowClipToBackgroundRectWithGeometryMapper( |
| 285 context, clipRectWithGeometryMapper(context, false)); |
| 286 backgroundRect.move( |
| 287 context.subPixelAccumulation); // TODO(chrishtr): is this needed? |
| 288 backgroundRect.intersect(paintDirtyRect); |
| 289 |
| 290 foregroundRect.move( |
| 291 context.subPixelAccumulation); // TODO(chrishtr): is this needed? |
| 292 foregroundRect = clipRectWithGeometryMapper(context, true); |
| 293 foregroundRect.intersect(paintDirtyRect); |
| 294 LayoutPoint offset; |
| 295 if (offsetFromRoot) |
| 296 offset = *offsetFromRoot; |
| 297 else |
| 298 m_layer.convertToLayerCoords(context.rootLayer, offset); |
| 299 layerBounds = LayoutRect(offset, LayoutSize(m_layer.size())); |
| 300 |
| 301 #ifdef CHECK_CLIP_RECTS |
| 302 ClipRect testBackgroundRect, testForegroundRect; |
| 303 LayoutRect testLayerBounds; |
| 304 PaintLayerClipper(m_layer, false) |
| 305 .calculateRects(context, paintDirtyRect, testLayerBounds, |
| 306 testBackgroundRect, testForegroundRect); |
| 307 CHECK_RECTS_EQ(testBackgroundRect, backgroundRect); |
| 308 CHECK_RECTS_EQ(testForegroundRect, foregroundRect); |
| 309 CHECK_RECTS_EQ(testLayerBounds, layerBounds); |
| 310 #endif |
| 311 } |
| 312 |
213 void PaintLayerClipper::calculateRects( | 313 void PaintLayerClipper::calculateRects( |
214 const ClipRectsContext& context, | 314 const ClipRectsContext& context, |
215 const LayoutRect& paintDirtyRect, | 315 const LayoutRect& paintDirtyRect, |
216 LayoutRect& layerBounds, | 316 LayoutRect& layerBounds, |
217 ClipRect& backgroundRect, | 317 ClipRect& backgroundRect, |
218 ClipRect& foregroundRect, | 318 ClipRect& foregroundRect, |
219 const LayoutPoint* offsetFromRoot) const { | 319 const LayoutPoint* offsetFromRoot) const { |
| 320 if (m_geometryMapper) { |
| 321 calculateRectsWithGeometryMapper(context, paintDirtyRect, layerBounds, |
| 322 backgroundRect, foregroundRect, |
| 323 offsetFromRoot); |
| 324 return; |
| 325 } |
| 326 |
220 bool isClippingRoot = &m_layer == context.rootLayer; | 327 bool isClippingRoot = &m_layer == context.rootLayer; |
221 LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); | 328 LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); |
222 | 329 |
223 if (!isClippingRoot && m_layer.parent()) { | 330 if (!isClippingRoot && m_layer.parent()) { |
224 backgroundRect = backgroundClipRect(context); | 331 backgroundRect = backgroundClipRect(context); |
225 backgroundRect.move(context.subPixelAccumulation); | 332 backgroundRect.move(context.subPixelAccumulation); |
226 backgroundRect.intersect(paintDirtyRect); | 333 backgroundRect.intersect(paintDirtyRect); |
227 } else { | 334 } else { |
228 backgroundRect = paintDirtyRect; | 335 backgroundRect = paintDirtyRect; |
229 } | 336 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; | 400 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; |
294 // Ensure that our parent's clip has been calculated so that we can examine | 401 // Ensure that our parent's clip has been calculated so that we can examine |
295 // the values. | 402 // the values. |
296 if (parentLayer) { | 403 if (parentLayer) { |
297 parentLayer->clipper().getOrCalculateClipRects(context, clipRects); | 404 parentLayer->clipper().getOrCalculateClipRects(context, clipRects); |
298 } else { | 405 } else { |
299 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); | 406 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); |
300 } | 407 } |
301 | 408 |
302 adjustClipRectsForChildren(layoutObject, clipRects); | 409 adjustClipRectsForChildren(layoutObject, clipRects); |
303 | |
304 if ((layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || | 410 if ((layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || |
305 (layoutObject.isSVGRoot() && | 411 (layoutObject.isSVGRoot() && |
306 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || | 412 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || |
307 layoutObject.hasClip() || layoutObject.styleRef().containsPaint()) { | 413 layoutObject.hasClip() || layoutObject.styleRef().containsPaint()) { |
308 // This offset cannot use convertToLayerCoords, because sometimes our | 414 // This offset cannot use convertToLayerCoords, because sometimes our |
309 // rootLayer may be across some transformed layer boundary, for example, in | 415 // rootLayer may be across some transformed layer boundary, for example, in |
310 // the PaintLayerCompositor overlapMap, where clipRects are needed in view | 416 // the PaintLayerCompositor overlapMap, where clipRects are needed in view |
311 // space. | 417 // space. |
312 applyClipRects(context, layoutObject, | 418 applyClipRects(context, layoutObject, |
313 roundedLayoutPoint(layoutObject.localToAncestorPoint( | 419 roundedLayoutPoint(layoutObject.localToAncestorPoint( |
314 FloatPoint(), context.rootLayer->layoutObject())), | 420 FloatPoint(), context.rootLayer->layoutObject())), |
315 clipRects); | 421 clipRects); |
316 } | 422 } |
317 } | 423 } |
318 | 424 |
319 static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, | 425 static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, |
320 EPosition position) { | 426 EPosition position) { |
321 if (position == FixedPosition) | 427 if (position == FixedPosition) |
322 return parentRects.fixedClipRect(); | 428 return parentRects.fixedClipRect(); |
323 | 429 |
324 if (position == AbsolutePosition) | 430 if (position == AbsolutePosition) |
325 return parentRects.posClipRect(); | 431 return parentRects.posClipRect(); |
326 | 432 |
327 return parentRects.overflowClipRect(); | 433 return parentRects.overflowClipRect(); |
328 } | 434 } |
329 | 435 |
| 436 ClipRect PaintLayerClipper::clipRectWithGeometryMapper( |
| 437 const ClipRectsContext& context, |
| 438 bool isForeground) const { |
| 439 DCHECK(m_geometryMapper); |
| 440 LayoutRect source(LayoutRect::infiniteIntRect()); |
| 441 bool success = false; |
| 442 const ObjectPaintProperties* properties = |
| 443 m_layer.layoutObject()->objectPaintProperties(); |
| 444 PropertyTreeState propertyTreeState = |
| 445 properties->localBorderBoxProperties()->propertyTreeState; |
| 446 |
| 447 if (properties->cssClip()) |
| 448 propertyTreeState.setClip(properties->cssClip()); |
| 449 |
| 450 const LayoutObject& layoutObject = *m_layer.layoutObject(); |
| 451 if (shouldRespectOverflowClip(context) && isForeground && |
| 452 (layoutObject.hasOverflowClip() || |
| 453 layoutObject.styleRef().containsPaint())) { |
| 454 if (properties->overflowClip()) |
| 455 propertyTreeState.setClip(properties->overflowClip()); |
| 456 } |
| 457 |
| 458 const ObjectPaintProperties* ancestorProperties = |
| 459 context.rootLayer->layoutObject()->objectPaintProperties(); |
| 460 PropertyTreeState destinationPropertyTreeState = |
| 461 ancestorProperties->localBorderBoxProperties()->propertyTreeState; |
| 462 if (!context.rootLayer->clipper().shouldRespectOverflowClip(context)) { |
| 463 if (ancestorProperties->overflowClip()) |
| 464 destinationPropertyTreeState.setClip(ancestorProperties->overflowClip()); |
| 465 } |
| 466 FloatRect clippedRectInRootLayerSpace = |
| 467 m_geometryMapper->mapToVisualRectInDestinationSpace( |
| 468 FloatRect(source), propertyTreeState, destinationPropertyTreeState, |
| 469 success); |
| 470 DCHECK(success); |
| 471 return ClipRect(LayoutRect(clippedRectInRootLayerSpace)); |
| 472 } |
| 473 |
| 474 ClipRect PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper( |
| 475 const ClipRectsContext& context, |
| 476 const ClipRect& clip) const { |
| 477 const LayoutObject& layoutObject = *m_layer.layoutObject(); |
| 478 FloatRect clipRect(clip.rect()); |
| 479 if ((layoutObject.hasOverflowClip() || |
| 480 layoutObject.styleRef().containsPaint()) && |
| 481 shouldRespectOverflowClip(context)) { |
| 482 LayoutRect layerBoundsWithVisualOverflow = |
| 483 layoutObject.isLayoutView() |
| 484 ? toLayoutView(layoutObject).viewRect() |
| 485 : toLayoutBox(layoutObject).visualOverflowRect(); |
| 486 toLayoutBox(layoutObject) |
| 487 .flipForWritingMode( |
| 488 layerBoundsWithVisualOverflow); // PaintLayer are in physical coord
inates, so the overflow has to be flipped. |
| 489 mapLocalToRootWithGeometryMapper(context, layerBoundsWithVisualOverflow); |
| 490 clipRect.intersect(FloatRect(layerBoundsWithVisualOverflow)); |
| 491 } |
| 492 |
| 493 return ClipRect(LayoutRect(clipRect)); |
| 494 } |
| 495 |
330 ClipRect PaintLayerClipper::backgroundClipRect( | 496 ClipRect PaintLayerClipper::backgroundClipRect( |
331 const ClipRectsContext& context) const { | 497 const ClipRectsContext& context) const { |
| 498 if (m_geometryMapper) { |
| 499 ClipRect backgroundClipRect = clipRectWithGeometryMapper(context, false); |
| 500 #ifdef CHECK_CLIP_RECTS |
| 501 ClipRect testBackgroundClipRect = |
| 502 PaintLayerClipper(m_layer, false).backgroundClipRect(context); |
| 503 CHECK_RECTS_EQ(testBackgroundClipRect, backgroundClipRect); |
| 504 #endif |
| 505 return backgroundClipRect; |
| 506 } |
| 507 |
332 DCHECK(m_layer.parent()); | 508 DCHECK(m_layer.parent()); |
333 LayoutView* layoutView = m_layer.layoutObject()->view(); | 509 LayoutView* layoutView = m_layer.layoutObject()->view(); |
334 DCHECK(layoutView); | 510 DCHECK(layoutView); |
335 | 511 |
336 RefPtr<ClipRects> parentClipRects = ClipRects::create(); | 512 RefPtr<ClipRects> parentClipRects = ClipRects::create(); |
337 if (&m_layer == context.rootLayer) | 513 if (&m_layer == context.rootLayer) |
338 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); | 514 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); |
339 else | 515 else |
340 m_layer.parent()->clipper().getOrCalculateClipRects(context, | 516 m_layer.parent()->clipper().getOrCalculateClipRects(context, |
341 *parentClipRects); | 517 *parentClipRects); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
373 context.respectOverflowClipForViewport == IgnoreOverflowClip) | 549 context.respectOverflowClipForViewport == IgnoreOverflowClip) |
374 return false; | 550 return false; |
375 | 551 |
376 return true; | 552 return true; |
377 } | 553 } |
378 | 554 |
379 ClipRects& PaintLayerClipper::paintingClipRects( | 555 ClipRects& PaintLayerClipper::paintingClipRects( |
380 const PaintLayer* rootLayer, | 556 const PaintLayer* rootLayer, |
381 ShouldRespectOverflowClipType respectOverflowClip, | 557 ShouldRespectOverflowClipType respectOverflowClip, |
382 const LayoutSize& subpixelAccumulation) const { | 558 const LayoutSize& subpixelAccumulation) const { |
| 559 DCHECK(!m_geometryMapper); |
383 ClipRectsContext context(rootLayer, PaintingClipRects, | 560 ClipRectsContext context(rootLayer, PaintingClipRects, |
384 IgnoreOverlayScrollbarSize, subpixelAccumulation); | 561 IgnoreOverlayScrollbarSize, subpixelAccumulation); |
385 if (respectOverflowClip == IgnoreOverflowClip) | 562 if (respectOverflowClip == IgnoreOverflowClip) |
386 context.setIgnoreOverflowClip(); | 563 context.setIgnoreOverflowClip(); |
387 return getClipRects(context); | 564 return getClipRects(context); |
388 } | 565 } |
389 | 566 |
390 } // namespace blink | 567 } // namespace blink |
OLD | NEW |