| 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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/paint/ObjectPaintProperties.h" | 50 #include "core/paint/ObjectPaintProperties.h" |
| 51 #include "core/paint/PaintLayer.h" | 51 #include "core/paint/PaintLayer.h" |
| 52 #include "platform/graphics/paint/GeometryMapper.h" |
| 52 | 53 |
| 53 namespace blink { | 54 namespace blink { |
| 54 | 55 |
| 55 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, | 56 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, |
| 56 ClipRects& clipRects) { | 57 ClipRects& clipRects) { |
| 57 EPosition position = layoutObject.styleRef().position(); | 58 EPosition position = layoutObject.styleRef().position(); |
| 58 // A fixed object is essentially the root of its containing block hierarchy, | 59 // 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 | 60 // so when we encounter such an object, we reset our clip rects to the |
| 60 // fixedClipRect. | 61 // fixedClipRect. |
| 61 if (position == EPosition::kFixed) { | 62 if (position == EPosition::kFixed) { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 LayoutRect newClip = box.clipRect(offset); | 103 LayoutRect newClip = box.clipRect(offset); |
| 103 clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect())); | 104 clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect())); |
| 104 clipRects.setOverflowClipRect( | 105 clipRects.setOverflowClipRect( |
| 105 intersection(newClip, clipRects.overflowClipRect())); | 106 intersection(newClip, clipRects.overflowClipRect())); |
| 106 clipRects.setFixedClipRect( | 107 clipRects.setFixedClipRect( |
| 107 intersection(newClip, clipRects.fixedClipRect())); | 108 intersection(newClip, clipRects.fixedClipRect())); |
| 108 } | 109 } |
| 109 } | 110 } |
| 110 | 111 |
| 111 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer, | 112 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer, |
| 112 GeometryMapper* geometryMapper) | 113 bool usegeometryMapper) |
| 113 : m_layer(layer), m_geometryMapper(geometryMapper) {} | 114 : m_layer(layer), m_useGeometryMapper(usegeometryMapper) {} |
| 114 | 115 |
| 115 ClipRects* PaintLayerClipper::clipRectsIfCached( | 116 ClipRects* PaintLayerClipper::clipRectsIfCached( |
| 116 const ClipRectsContext& context) const { | 117 const ClipRectsContext& context) const { |
| 117 DCHECK(context.usesCache()); | 118 DCHECK(context.usesCache()); |
| 118 if (!m_layer.clipRectsCache()) | 119 if (!m_layer.clipRectsCache()) |
| 119 return nullptr; | 120 return nullptr; |
| 120 ClipRectsCache::Entry& entry = | 121 ClipRectsCache::Entry& entry = |
| 121 m_layer.clipRectsCache()->get(context.cacheSlot()); | 122 m_layer.clipRectsCache()->get(context.cacheSlot()); |
| 122 // FIXME: We used to ASSERT that we always got a consistent root layer. | 123 // FIXME: We used to ASSERT that we always got a consistent root layer. |
| 123 // We should add a test that has an inconsistent root. See | 124 // We should add a test that has an inconsistent root. See |
| (...skipping 23 matching lines...) Expand all Loading... |
| 147 entry.clipRects = parentClipRects; | 148 entry.clipRects = parentClipRects; |
| 148 return *parentClipRects; | 149 return *parentClipRects; |
| 149 } | 150 } |
| 150 } | 151 } |
| 151 entry.clipRects = ClipRects::create(clipRects); | 152 entry.clipRects = ClipRects::create(clipRects); |
| 152 return *entry.clipRects; | 153 return *entry.clipRects; |
| 153 } | 154 } |
| 154 | 155 |
| 155 ClipRects& PaintLayerClipper::getClipRects( | 156 ClipRects& PaintLayerClipper::getClipRects( |
| 156 const ClipRectsContext& context) const { | 157 const ClipRectsContext& context) const { |
| 157 DCHECK(!m_geometryMapper); | 158 DCHECK(!m_useGeometryMapper); |
| 158 if (ClipRects* result = clipRectsIfCached(context)) | 159 if (ClipRects* result = clipRectsIfCached(context)) |
| 159 return *result; | 160 return *result; |
| 160 // Note that it's important that we call getClipRects on our parent | 161 // Note that it's important that we call getClipRects on our parent |
| 161 // before we call calculateClipRects so that calculateClipRects will hit | 162 // before we call calculateClipRects so that calculateClipRects will hit |
| 162 // the cache. | 163 // the cache. |
| 163 ClipRects* parentClipRects = nullptr; | 164 ClipRects* parentClipRects = nullptr; |
| 164 if (context.rootLayer != &m_layer && m_layer.parent()) { | 165 if (context.rootLayer != &m_layer && m_layer.parent()) { |
| 165 parentClipRects = | 166 parentClipRects = |
| 166 &PaintLayerClipper(*m_layer.parent(), nullptr).getClipRects(context); | 167 &PaintLayerClipper(*m_layer.parent(), false).getClipRects(context); |
| 167 } | 168 } |
| 168 RefPtr<ClipRects> clipRects = ClipRects::create(); | 169 RefPtr<ClipRects> clipRects = ClipRects::create(); |
| 169 calculateClipRects(context, *clipRects); | 170 calculateClipRects(context, *clipRects); |
| 170 return storeClipRectsInCache(context, parentClipRects, *clipRects); | 171 return storeClipRectsInCache(context, parentClipRects, *clipRects); |
| 171 } | 172 } |
| 172 | 173 |
| 173 void PaintLayerClipper::clearCache(ClipRectsCacheSlot cacheSlot) { | 174 void PaintLayerClipper::clearCache(ClipRectsCacheSlot cacheSlot) { |
| 174 if (cacheSlot == NumberOfClipRectsCacheSlots) | 175 if (cacheSlot == NumberOfClipRectsCacheSlots) |
| 175 m_layer.clearClipRectsCache(); | 176 m_layer.clearClipRectsCache(); |
| 176 else if (ClipRectsCache* cache = m_layer.clipRectsCache()) | 177 else if (ClipRectsCache* cache = m_layer.clipRectsCache()) |
| 177 cache->clear(cacheSlot); | 178 cache->clear(cacheSlot); |
| 178 } | 179 } |
| 179 | 180 |
| 180 void PaintLayerClipper::clearClipRectsIncludingDescendants() { | 181 void PaintLayerClipper::clearClipRectsIncludingDescendants() { |
| 181 clearClipRectsIncludingDescendants(NumberOfClipRectsCacheSlots); | 182 clearClipRectsIncludingDescendants(NumberOfClipRectsCacheSlots); |
| 182 } | 183 } |
| 183 | 184 |
| 184 void PaintLayerClipper::clearClipRectsIncludingDescendants( | 185 void PaintLayerClipper::clearClipRectsIncludingDescendants( |
| 185 ClipRectsCacheSlot cacheSlot) { | 186 ClipRectsCacheSlot cacheSlot) { |
| 186 std::stack<const PaintLayer*> layers; | 187 std::stack<const PaintLayer*> layers; |
| 187 layers.push(&m_layer); | 188 layers.push(&m_layer); |
| 188 | 189 |
| 189 while (!layers.empty()) { | 190 while (!layers.empty()) { |
| 190 const PaintLayer* currentLayer = layers.top(); | 191 const PaintLayer* currentLayer = layers.top(); |
| 191 layers.pop(); | 192 layers.pop(); |
| 192 PaintLayerClipper(*currentLayer, m_geometryMapper).clearCache(cacheSlot); | 193 PaintLayerClipper(*currentLayer, m_useGeometryMapper).clearCache(cacheSlot); |
| 193 for (const PaintLayer* layer = currentLayer->firstChild(); layer; | 194 for (const PaintLayer* layer = currentLayer->firstChild(); layer; |
| 194 layer = layer->nextSibling()) | 195 layer = layer->nextSibling()) |
| 195 layers.push(layer); | 196 layers.push(layer); |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 | 199 |
| 199 LayoutRect PaintLayerClipper::localClipRect( | 200 LayoutRect PaintLayerClipper::localClipRect( |
| 200 const PaintLayer& clippingRootLayer) const { | 201 const PaintLayer& clippingRootLayer) const { |
| 201 ClipRectsContext context(&clippingRootLayer, PaintingClipRects); | 202 ClipRectsContext context(&clippingRootLayer, PaintingClipRects); |
| 202 if (m_geometryMapper) { | 203 if (m_useGeometryMapper) { |
| 203 ClipRect clipRect; | 204 ClipRect clipRect; |
| 204 calculateBackgroundClipRectWithGeometryMapper(context, clipRect); | 205 calculateBackgroundClipRectWithGeometryMapper(context, clipRect); |
| 205 LayoutRect premappedRect = clipRect.rect(); | 206 LayoutRect premappedRect = clipRect.rect(); |
| 206 | 207 |
| 207 // The rect now needs to be transformed to the local space of this | 208 // The rect now needs to be transformed to the local space of this |
| 208 // PaintLayer. | 209 // PaintLayer. |
| 209 premappedRect.moveBy(context.rootLayer->layoutObject().paintOffset()); | 210 premappedRect.moveBy(context.rootLayer->layoutObject().paintOffset()); |
| 210 | 211 |
| 211 const auto* clipRootLayerTransform = clippingRootLayer.layoutObject() | 212 const auto* clipRootLayerTransform = clippingRootLayer.layoutObject() |
| 212 .localBorderBoxProperties() | 213 .localBorderBoxProperties() |
| 213 ->transform(); | 214 ->transform(); |
| 214 const auto* layerTransform = | 215 const auto* layerTransform = |
| 215 m_layer.layoutObject().localBorderBoxProperties()->transform(); | 216 m_layer.layoutObject().localBorderBoxProperties()->transform(); |
| 216 FloatRect clippedRectInLocalSpace(premappedRect); | 217 FloatRect clippedRectInLocalSpace(premappedRect); |
| 217 m_geometryMapper->sourceToDestinationRect( | 218 GeometryMapper::sourceToDestinationRect( |
| 218 clipRootLayerTransform, layerTransform, clippedRectInLocalSpace); | 219 clipRootLayerTransform, layerTransform, clippedRectInLocalSpace); |
| 219 clippedRectInLocalSpace.moveBy( | 220 clippedRectInLocalSpace.moveBy( |
| 220 -FloatPoint(m_layer.layoutObject().paintOffset())); | 221 -FloatPoint(m_layer.layoutObject().paintOffset())); |
| 221 | 222 |
| 222 return LayoutRect(clippedRectInLocalSpace); | 223 return LayoutRect(clippedRectInLocalSpace); |
| 223 } | 224 } |
| 224 | 225 |
| 225 LayoutRect layerBounds; | 226 LayoutRect layerBounds; |
| 226 ClipRect backgroundRect, foregroundRect; | 227 ClipRect backgroundRect, foregroundRect; |
| 227 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), | 228 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 287 #endif | 288 #endif |
| 288 } | 289 } |
| 289 | 290 |
| 290 void PaintLayerClipper::calculateRects( | 291 void PaintLayerClipper::calculateRects( |
| 291 const ClipRectsContext& context, | 292 const ClipRectsContext& context, |
| 292 const LayoutRect& paintDirtyRect, | 293 const LayoutRect& paintDirtyRect, |
| 293 LayoutRect& layerBounds, | 294 LayoutRect& layerBounds, |
| 294 ClipRect& backgroundRect, | 295 ClipRect& backgroundRect, |
| 295 ClipRect& foregroundRect, | 296 ClipRect& foregroundRect, |
| 296 const LayoutPoint* offsetFromRoot) const { | 297 const LayoutPoint* offsetFromRoot) const { |
| 297 if (m_geometryMapper) { | 298 if (m_useGeometryMapper) { |
| 298 calculateRectsWithGeometryMapper(context, paintDirtyRect, layerBounds, | 299 calculateRectsWithGeometryMapper(context, paintDirtyRect, layerBounds, |
| 299 backgroundRect, foregroundRect, | 300 backgroundRect, foregroundRect, |
| 300 offsetFromRoot); | 301 offsetFromRoot); |
| 301 return; | 302 return; |
| 302 } | 303 } |
| 303 | 304 |
| 304 bool isClippingRoot = &m_layer == context.rootLayer; | 305 bool isClippingRoot = &m_layer == context.rootLayer; |
| 305 LayoutBoxModelObject& layoutObject = m_layer.layoutObject(); | 306 LayoutBoxModelObject& layoutObject = m_layer.layoutObject(); |
| 306 | 307 |
| 307 if (!isClippingRoot && m_layer.parent()) { | 308 if (!isClippingRoot && m_layer.parent()) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 360 | 361 |
| 361 bool isClippingRoot = &m_layer == context.rootLayer; | 362 bool isClippingRoot = &m_layer == context.rootLayer; |
| 362 | 363 |
| 363 // For transformed layers, the root layer was shifted to be us, so there is no | 364 // For transformed layers, the root layer was shifted to be us, so there is no |
| 364 // need to examine the parent. We want to cache clip rects with us as the | 365 // need to examine the parent. We want to cache clip rects with us as the |
| 365 // root. | 366 // root. |
| 366 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; | 367 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; |
| 367 // Ensure that our parent's clip has been calculated so that we can examine | 368 // Ensure that our parent's clip has been calculated so that we can examine |
| 368 // the values. | 369 // the values. |
| 369 if (parentLayer) { | 370 if (parentLayer) { |
| 370 PaintLayerClipper(*parentLayer, m_geometryMapper) | 371 PaintLayerClipper(*parentLayer, m_useGeometryMapper) |
| 371 .getOrCalculateClipRects(context, clipRects); | 372 .getOrCalculateClipRects(context, clipRects); |
| 372 } else { | 373 } else { |
| 373 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); | 374 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 374 } | 375 } |
| 375 | 376 |
| 376 adjustClipRectsForChildren(layoutObject, clipRects); | 377 adjustClipRectsForChildren(layoutObject, clipRects); |
| 377 | 378 |
| 378 if (shouldClipOverflow(context) || layoutObject.hasClip()) { | 379 if (shouldClipOverflow(context) || layoutObject.hasClip()) { |
| 379 // This offset cannot use convertToLayerCoords, because sometimes our | 380 // This offset cannot use convertToLayerCoords, because sometimes our |
| 380 // rootLayer may be across some transformed layer boundary, for example, in | 381 // rootLayer may be across some transformed layer boundary, for example, in |
| (...skipping 13 matching lines...) Expand all Loading... |
| 394 | 395 |
| 395 if (position == EPosition::kAbsolute) | 396 if (position == EPosition::kAbsolute) |
| 396 return parentRects.posClipRect(); | 397 return parentRects.posClipRect(); |
| 397 | 398 |
| 398 return parentRects.overflowClipRect(); | 399 return parentRects.overflowClipRect(); |
| 399 } | 400 } |
| 400 | 401 |
| 401 void PaintLayerClipper::calculateBackgroundClipRectWithGeometryMapper( | 402 void PaintLayerClipper::calculateBackgroundClipRectWithGeometryMapper( |
| 402 const ClipRectsContext& context, | 403 const ClipRectsContext& context, |
| 403 ClipRect& output) const { | 404 ClipRect& output) const { |
| 404 DCHECK(m_geometryMapper); | 405 DCHECK(m_useGeometryMapper); |
| 405 PropertyTreeState sourcePropertyTreeState(nullptr, nullptr, nullptr); | 406 PropertyTreeState sourcePropertyTreeState(nullptr, nullptr, nullptr); |
| 406 PropertyTreeState destinationPropertyTreeState(nullptr, nullptr, nullptr); | 407 PropertyTreeState destinationPropertyTreeState(nullptr, nullptr, nullptr); |
| 407 initializeCommonClipRectState(context, sourcePropertyTreeState, | 408 initializeCommonClipRectState(context, sourcePropertyTreeState, |
| 408 destinationPropertyTreeState); | 409 destinationPropertyTreeState); |
| 409 | 410 |
| 410 if (&m_layer != context.rootLayer) { | 411 if (&m_layer != context.rootLayer) { |
| 411 auto* ancestorProperties = | 412 auto* ancestorProperties = |
| 412 context.rootLayer->layoutObject().paintProperties(); | 413 context.rootLayer->layoutObject().paintProperties(); |
| 413 const auto* ancestorOverflowClip = | 414 const auto* ancestorOverflowClip = |
| 414 ancestorProperties ? ancestorProperties->overflowClip() : nullptr; | 415 ancestorProperties ? ancestorProperties->overflowClip() : nullptr; |
| 415 // Set the clip of |destinationPropertyTreeState| to be inside the | 416 // Set the clip of |destinationPropertyTreeState| to be inside the |
| 416 // ancestor's overflow clip, so that that clip is not applied. | 417 // ancestor's overflow clip, so that that clip is not applied. |
| 417 if (context.respectOverflowClip == IgnoreOverflowClip && | 418 if (context.respectOverflowClip == IgnoreOverflowClip && |
| 418 ancestorOverflowClip) | 419 ancestorOverflowClip) |
| 419 destinationPropertyTreeState.setClip(ancestorOverflowClip); | 420 destinationPropertyTreeState.setClip(ancestorOverflowClip); |
| 420 } | 421 } |
| 421 | 422 |
| 422 // The background rect applies all clips *above* m_layer, but not the overflow | 423 // The background rect applies all clips *above* m_layer, but not the overflow |
| 423 // clip of m_layer. It also applies a clip to the total painting bounds | 424 // clip of m_layer. It also applies a clip to the total painting bounds |
| 424 // of m_layer, because nothing in m_layer or its children within the clip can | 425 // of m_layer, because nothing in m_layer or its children within the clip can |
| 425 // paint outside of those bounds. | 426 // paint outside of those bounds. |
| 426 // The total painting bounds includes any visual overflow (such as shadow) and | 427 // The total painting bounds includes any visual overflow (such as shadow) and |
| 427 // filter bounds. | 428 // filter bounds. |
| 428 if (shouldClipOverflow(context)) { | 429 if (shouldClipOverflow(context)) { |
| 429 FloatRect clipRect(localVisualRect()); | 430 FloatRect clipRect(localVisualRect()); |
| 430 clipRect.moveBy(FloatPoint(m_layer.layoutObject().paintOffset())); | 431 clipRect.moveBy(FloatPoint(m_layer.layoutObject().paintOffset())); |
| 431 m_geometryMapper->sourceToDestinationVisualRect( | 432 GeometryMapper::sourceToDestinationVisualRect( |
| 432 sourcePropertyTreeState, destinationPropertyTreeState, clipRect); | 433 sourcePropertyTreeState, destinationPropertyTreeState, clipRect); |
| 433 output.setRect(FloatClipRect(clipRect)); | 434 output.setRect(FloatClipRect(clipRect)); |
| 434 } else { | 435 } else { |
| 435 const FloatClipRect& clippedRectInRootLayerSpace = | 436 const FloatClipRect& clippedRectInRootLayerSpace = |
| 436 m_geometryMapper->sourceToDestinationClipRect( | 437 GeometryMapper::sourceToDestinationClipRect( |
| 437 sourcePropertyTreeState, destinationPropertyTreeState); | 438 sourcePropertyTreeState, destinationPropertyTreeState); |
| 438 output.setRect(clippedRectInRootLayerSpace); | 439 output.setRect(clippedRectInRootLayerSpace); |
| 439 } | 440 } |
| 440 | 441 |
| 441 output.moveBy(-context.rootLayer->layoutObject().paintOffset()); | 442 output.moveBy(-context.rootLayer->layoutObject().paintOffset()); |
| 442 } | 443 } |
| 443 | 444 |
| 444 void PaintLayerClipper::initializeCommonClipRectState( | 445 void PaintLayerClipper::initializeCommonClipRectState( |
| 445 const ClipRectsContext& context, | 446 const ClipRectsContext& context, |
| 446 PropertyTreeState& sourcePropertyTreeState, | 447 PropertyTreeState& sourcePropertyTreeState, |
| 447 PropertyTreeState& destinationPropertyTreeState) const { | 448 PropertyTreeState& destinationPropertyTreeState) const { |
| 448 DCHECK(m_geometryMapper); | 449 DCHECK(m_useGeometryMapper); |
| 449 DCHECK(m_layer.layoutObject().localBorderBoxProperties()); | 450 DCHECK(m_layer.layoutObject().localBorderBoxProperties()); |
| 450 | 451 |
| 451 sourcePropertyTreeState = *m_layer.layoutObject().localBorderBoxProperties(); | 452 sourcePropertyTreeState = *m_layer.layoutObject().localBorderBoxProperties(); |
| 452 DCHECK(context.rootLayer->layoutObject().localBorderBoxProperties()); | 453 DCHECK(context.rootLayer->layoutObject().localBorderBoxProperties()); |
| 453 destinationPropertyTreeState = | 454 destinationPropertyTreeState = |
| 454 *context.rootLayer->layoutObject().localBorderBoxProperties(); | 455 *context.rootLayer->layoutObject().localBorderBoxProperties(); |
| 455 | 456 |
| 456 auto* ancestorProperties = | 457 auto* ancestorProperties = |
| 457 context.rootLayer->layoutObject().paintProperties(); | 458 context.rootLayer->layoutObject().paintProperties(); |
| 458 const auto* ancestorCssClip = | 459 const auto* ancestorCssClip = |
| 459 ancestorProperties ? ancestorProperties->cssClip() : nullptr; | 460 ancestorProperties ? ancestorProperties->cssClip() : nullptr; |
| 460 // CSS clip of the root is always applied. | 461 // CSS clip of the root is always applied. |
| 461 if (ancestorCssClip) { | 462 if (ancestorCssClip) { |
| 462 DCHECK(destinationPropertyTreeState.clip() == | 463 DCHECK(destinationPropertyTreeState.clip() == |
| 463 ancestorProperties->cssClip()); | 464 ancestorProperties->cssClip()); |
| 464 destinationPropertyTreeState.setClip(ancestorCssClip->parent()); | 465 destinationPropertyTreeState.setClip(ancestorCssClip->parent()); |
| 465 } | 466 } |
| 466 } | 467 } |
| 467 | 468 |
| 468 void PaintLayerClipper::calculateForegroundClipRectWithGeometryMapper( | 469 void PaintLayerClipper::calculateForegroundClipRectWithGeometryMapper( |
| 469 const ClipRectsContext& context, | 470 const ClipRectsContext& context, |
| 470 ClipRect& output) const { | 471 ClipRect& output) const { |
| 471 DCHECK(m_geometryMapper); | 472 DCHECK(m_useGeometryMapper); |
| 472 PropertyTreeState sourcePropertyTreeState(nullptr, nullptr, nullptr); | 473 PropertyTreeState sourcePropertyTreeState(nullptr, nullptr, nullptr); |
| 473 PropertyTreeState destinationPropertyTreeState(nullptr, nullptr, nullptr); | 474 PropertyTreeState destinationPropertyTreeState(nullptr, nullptr, nullptr); |
| 474 initializeCommonClipRectState(context, sourcePropertyTreeState, | 475 initializeCommonClipRectState(context, sourcePropertyTreeState, |
| 475 destinationPropertyTreeState); | 476 destinationPropertyTreeState); |
| 476 const auto* properties = m_layer.layoutObject().paintProperties(); | 477 const auto* properties = m_layer.layoutObject().paintProperties(); |
| 477 | 478 |
| 478 if (&m_layer == context.rootLayer) { | 479 if (&m_layer == context.rootLayer) { |
| 479 // Set the overflow clip for |sourcePropertyTreeState| so that it differs | 480 // Set the overflow clip for |sourcePropertyTreeState| so that it differs |
| 480 // from |destinationPropertyTreeState| in its clip. | 481 // from |destinationPropertyTreeState| in its clip. |
| 481 if (context.respectOverflowClip == RespectOverflowClip && properties && | 482 if (context.respectOverflowClip == RespectOverflowClip && properties && |
| 482 properties->overflowClip()) | 483 properties->overflowClip()) |
| 483 sourcePropertyTreeState.setClip(properties->overflowClip()); | 484 sourcePropertyTreeState.setClip(properties->overflowClip()); |
| 484 } else { | 485 } else { |
| 485 const auto* ancestorProperties = | 486 const auto* ancestorProperties = |
| 486 context.rootLayer->layoutObject().paintProperties(); | 487 context.rootLayer->layoutObject().paintProperties(); |
| 487 | 488 |
| 488 // Set the clip of |destinationPropertyTreeState| to be inside the | 489 // Set the clip of |destinationPropertyTreeState| to be inside the |
| 489 // ancestor's overflow clip, so that that clip is not applied. | 490 // ancestor's overflow clip, so that that clip is not applied. |
| 490 if (context.respectOverflowClip == IgnoreOverflowClip && | 491 if (context.respectOverflowClip == IgnoreOverflowClip && |
| 491 ancestorProperties && ancestorProperties->overflowClip()) | 492 ancestorProperties && ancestorProperties->overflowClip()) |
| 492 destinationPropertyTreeState.setClip(ancestorProperties->overflowClip()); | 493 destinationPropertyTreeState.setClip(ancestorProperties->overflowClip()); |
| 493 | 494 |
| 494 // Set the overflow clip for |sourcePropertyTreeState| so that it differs | 495 // Set the overflow clip for |sourcePropertyTreeState| so that it differs |
| 495 // from destinationPropertyTreeState| in its clip. | 496 // from destinationPropertyTreeState| in its clip. |
| 496 if (properties && properties->overflowClip()) | 497 if (properties && properties->overflowClip()) |
| 497 sourcePropertyTreeState.setClip(properties->overflowClip()); | 498 sourcePropertyTreeState.setClip(properties->overflowClip()); |
| 498 } | 499 } |
| 499 | 500 |
| 500 const FloatClipRect& clippedRectInRootLayerSpace = | 501 const FloatClipRect& clippedRectInRootLayerSpace = |
| 501 m_geometryMapper->sourceToDestinationClipRect( | 502 GeometryMapper::sourceToDestinationClipRect(sourcePropertyTreeState, |
| 502 sourcePropertyTreeState, destinationPropertyTreeState); | 503 destinationPropertyTreeState); |
| 503 output.setRect(clippedRectInRootLayerSpace); | 504 output.setRect(clippedRectInRootLayerSpace); |
| 504 | 505 |
| 505 output.moveBy(-context.rootLayer->layoutObject().paintOffset()); | 506 output.moveBy(-context.rootLayer->layoutObject().paintOffset()); |
| 506 } | 507 } |
| 507 | 508 |
| 508 LayoutRect PaintLayerClipper::localVisualRect() const { | 509 LayoutRect PaintLayerClipper::localVisualRect() const { |
| 509 const LayoutObject& layoutObject = m_layer.layoutObject(); | 510 const LayoutObject& layoutObject = m_layer.layoutObject(); |
| 510 // The LayoutView is special since its overflow clipping rect may be larger | 511 // The LayoutView is special since its overflow clipping rect may be larger |
| 511 // than its box rect (crbug.com/492871). | 512 // than its box rect (crbug.com/492871). |
| 512 LayoutRect layerBoundsWithVisualOverflow = | 513 LayoutRect layerBoundsWithVisualOverflow = |
| 513 layoutObject.isLayoutView() | 514 layoutObject.isLayoutView() |
| 514 ? toLayoutView(layoutObject).viewRect() | 515 ? toLayoutView(layoutObject).viewRect() |
| 515 : toLayoutBox(layoutObject).visualOverflowRect(); | 516 : toLayoutBox(layoutObject).visualOverflowRect(); |
| 516 toLayoutBox(layoutObject) | 517 toLayoutBox(layoutObject) |
| 517 .flipForWritingMode( | 518 .flipForWritingMode( |
| 518 // PaintLayer are in physical coordinates, so the overflow has to be | 519 // PaintLayer are in physical coordinates, so the overflow has to be |
| 519 // flipped. | 520 // flipped. |
| 520 layerBoundsWithVisualOverflow); | 521 layerBoundsWithVisualOverflow); |
| 521 if (m_layer.paintsWithFilters()) { | 522 if (m_layer.paintsWithFilters()) { |
| 522 layerBoundsWithVisualOverflow = | 523 layerBoundsWithVisualOverflow = |
| 523 m_layer.mapLayoutRectForFilter(layerBoundsWithVisualOverflow); | 524 m_layer.mapLayoutRectForFilter(layerBoundsWithVisualOverflow); |
| 524 } | 525 } |
| 525 return layerBoundsWithVisualOverflow; | 526 return layerBoundsWithVisualOverflow; |
| 526 } | 527 } |
| 527 | 528 |
| 528 void PaintLayerClipper::calculateBackgroundClipRect( | 529 void PaintLayerClipper::calculateBackgroundClipRect( |
| 529 const ClipRectsContext& context, | 530 const ClipRectsContext& context, |
| 530 ClipRect& output) const { | 531 ClipRect& output) const { |
| 531 if (m_geometryMapper) { | 532 if (m_useGeometryMapper) { |
| 532 // TODO(chrishtr): fix the underlying bug that causes this situation. | 533 // TODO(chrishtr): fix the underlying bug that causes this situation. |
| 533 if (!m_layer.layoutObject().paintProperties() && | 534 if (!m_layer.layoutObject().paintProperties() && |
| 534 !m_layer.layoutObject().localBorderBoxProperties()) { | 535 !m_layer.layoutObject().localBorderBoxProperties()) { |
| 535 output.setRect(FloatClipRect()); | 536 output.setRect(FloatClipRect()); |
| 536 return; | 537 return; |
| 537 } | 538 } |
| 538 | 539 |
| 539 calculateBackgroundClipRectWithGeometryMapper(context, output); | 540 calculateBackgroundClipRectWithGeometryMapper(context, output); |
| 540 #ifdef CHECK_CLIP_RECTS | 541 #ifdef CHECK_CLIP_RECTS |
| 541 ClipRect testBackgroundClipRect = | 542 ClipRect testBackgroundClipRect = |
| 542 PaintLayerClipper(m_layer, nullptr).backgroundClipRect(context); | 543 PaintLayerClipper(m_layer, nullptr).backgroundClipRect(context); |
| 543 CHECK_RECTS_EQ(testBackgroundClipRect, output); | 544 CHECK_RECTS_EQ(testBackgroundClipRect, output); |
| 544 #endif | 545 #endif |
| 545 return; | 546 return; |
| 546 } | 547 } |
| 547 DCHECK(m_layer.parent()); | 548 DCHECK(m_layer.parent()); |
| 548 LayoutView* layoutView = m_layer.layoutObject().view(); | 549 LayoutView* layoutView = m_layer.layoutObject().view(); |
| 549 DCHECK(layoutView); | 550 DCHECK(layoutView); |
| 550 | 551 |
| 551 RefPtr<ClipRects> parentClipRects = ClipRects::create(); | 552 RefPtr<ClipRects> parentClipRects = ClipRects::create(); |
| 552 if (&m_layer == context.rootLayer) { | 553 if (&m_layer == context.rootLayer) { |
| 553 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); | 554 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 554 } else { | 555 } else { |
| 555 PaintLayerClipper(*m_layer.parent(), m_geometryMapper) | 556 PaintLayerClipper(*m_layer.parent(), m_useGeometryMapper) |
| 556 .getOrCalculateClipRects(context, *parentClipRects); | 557 .getOrCalculateClipRects(context, *parentClipRects); |
| 557 } | 558 } |
| 558 | 559 |
| 559 output = backgroundClipRectForPosition( | 560 output = backgroundClipRectForPosition( |
| 560 *parentClipRects, m_layer.layoutObject().styleRef().position()); | 561 *parentClipRects, m_layer.layoutObject().styleRef().position()); |
| 561 | 562 |
| 562 // Note: infinite clipRects should not be scrolled here, otherwise they will | 563 // Note: infinite clipRects should not be scrolled here, otherwise they will |
| 563 // accidentally no longer be considered infinite. | 564 // accidentally no longer be considered infinite. |
| 564 if (parentClipRects->fixed() && | 565 if (parentClipRects->fixed() && |
| 565 &context.rootLayer->layoutObject() == layoutView && | 566 &context.rootLayer->layoutObject() == layoutView && |
| 566 output != LayoutRect(LayoutRect::infiniteIntRect())) | 567 output != LayoutRect(LayoutRect::infiniteIntRect())) |
| 567 output.move(LayoutSize(layoutView->frameView()->getScrollOffset())); | 568 output.move(LayoutSize(layoutView->frameView()->getScrollOffset())); |
| 568 } | 569 } |
| 569 | 570 |
| 570 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, | 571 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, |
| 571 ClipRects& clipRects) const { | 572 ClipRects& clipRects) const { |
| 572 DCHECK(!m_geometryMapper); | 573 DCHECK(!m_useGeometryMapper); |
| 573 | 574 |
| 574 if (context.usesCache()) | 575 if (context.usesCache()) |
| 575 clipRects = getClipRects(context); | 576 clipRects = getClipRects(context); |
| 576 else | 577 else |
| 577 calculateClipRects(context, clipRects); | 578 calculateClipRects(context, clipRects); |
| 578 } | 579 } |
| 579 | 580 |
| 580 bool PaintLayerClipper::shouldClipOverflow( | 581 bool PaintLayerClipper::shouldClipOverflow( |
| 581 const ClipRectsContext& context) const { | 582 const ClipRectsContext& context) const { |
| 582 if (!m_layer.layoutObject().isBox()) | 583 if (!m_layer.layoutObject().isBox()) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 601 context.respectOverflowClipForViewport == IgnoreOverflowClip) | 602 context.respectOverflowClipForViewport == IgnoreOverflowClip) |
| 602 return false; | 603 return false; |
| 603 | 604 |
| 604 return true; | 605 return true; |
| 605 } | 606 } |
| 606 | 607 |
| 607 ClipRects& PaintLayerClipper::paintingClipRects( | 608 ClipRects& PaintLayerClipper::paintingClipRects( |
| 608 const PaintLayer* rootLayer, | 609 const PaintLayer* rootLayer, |
| 609 ShouldRespectOverflowClipType respectOverflowClip, | 610 ShouldRespectOverflowClipType respectOverflowClip, |
| 610 const LayoutSize& subpixelAccumulation) const { | 611 const LayoutSize& subpixelAccumulation) const { |
| 611 DCHECK(!m_geometryMapper); | 612 DCHECK(!m_useGeometryMapper); |
| 612 ClipRectsContext context(rootLayer, PaintingClipRects, | 613 ClipRectsContext context(rootLayer, PaintingClipRects, |
| 613 IgnorePlatformOverlayScrollbarSize, | 614 IgnorePlatformOverlayScrollbarSize, |
| 614 subpixelAccumulation); | 615 subpixelAccumulation); |
| 615 if (respectOverflowClip == IgnoreOverflowClip) | 616 if (respectOverflowClip == IgnoreOverflowClip) |
| 616 context.setIgnoreOverflowClip(); | 617 context.setIgnoreOverflowClip(); |
| 617 return getClipRects(context); | 618 return getClipRects(context); |
| 618 } | 619 } |
| 619 | 620 |
| 620 } // namespace blink | 621 } // namespace blink |
| OLD | NEW |