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