| 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 for (const PaintLayer* layer = currentLayer->firstChild(); layer; | 193 for (const PaintLayer* layer = currentLayer->firstChild(); layer; |
| 194 layer = layer->nextSibling()) | 194 layer = layer->nextSibling()) |
| 195 layers.push(layer); | 195 layers.push(layer); |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 | 198 |
| 199 LayoutRect PaintLayerClipper::localClipRect( | 199 LayoutRect PaintLayerClipper::localClipRect( |
| 200 const PaintLayer& clippingRootLayer) const { | 200 const PaintLayer& clippingRootLayer) const { |
| 201 ClipRectsContext context(&clippingRootLayer, PaintingClipRects); | 201 ClipRectsContext context(&clippingRootLayer, PaintingClipRects); |
| 202 if (m_geometryMapper) { | 202 if (m_geometryMapper) { |
| 203 ClipRect clipRect = clipRectWithGeometryMapper(context, false); | 203 ClipRect clipRect; |
| 204 calculateClipRectWithGeometryMapper(context, false, clipRect); |
| 204 applyOverflowClipToBackgroundRectWithGeometryMapper(context, clipRect); | 205 applyOverflowClipToBackgroundRectWithGeometryMapper(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 .paintProperties() | 213 .paintProperties() |
| 213 ->localBorderBoxProperties() | 214 ->localBorderBoxProperties() |
| 214 ->transform(); | 215 ->transform(); |
| 215 const auto* layerTransform = m_layer.layoutObject() | 216 const auto* layerTransform = m_layer.layoutObject() |
| 216 .paintProperties() | 217 .paintProperties() |
| 217 ->localBorderBoxProperties() | 218 ->localBorderBoxProperties() |
| 218 ->transform(); | 219 ->transform(); |
| 219 FloatRect clippedRectInLocalSpace = | 220 FloatRect clippedRectInLocalSpace(premappedRect); |
| 220 m_geometryMapper->sourceToDestinationRect( | 221 m_geometryMapper->sourceToDestinationRect( |
| 221 FloatRect(premappedRect), clipRootLayerTransform, layerTransform); | 222 clipRootLayerTransform, layerTransform, clippedRectInLocalSpace); |
| 222 clippedRectInLocalSpace.moveBy( | 223 clippedRectInLocalSpace.moveBy( |
| 223 -FloatPoint(m_layer.layoutObject().paintOffset())); | 224 -FloatPoint(m_layer.layoutObject().paintOffset())); |
| 224 | 225 |
| 225 return LayoutRect(clippedRectInLocalSpace); | 226 return LayoutRect(clippedRectInLocalSpace); |
| 226 } | 227 } |
| 227 | 228 |
| 228 LayoutRect layerBounds; | 229 LayoutRect layerBounds; |
| 229 ClipRect backgroundRect, foregroundRect; | 230 ClipRect backgroundRect, foregroundRect; |
| 230 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), | 231 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), |
| 231 layerBounds, backgroundRect, foregroundRect); | 232 layerBounds, backgroundRect, foregroundRect); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 263 | 264 |
| 264 const auto* layerTransform = m_layer.layoutObject() | 265 const auto* layerTransform = m_layer.layoutObject() |
| 265 .paintProperties() | 266 .paintProperties() |
| 266 ->localBorderBoxProperties() | 267 ->localBorderBoxProperties() |
| 267 ->transform(); | 268 ->transform(); |
| 268 const auto* rootTransform = context.rootLayer->layoutObject() | 269 const auto* rootTransform = context.rootLayer->layoutObject() |
| 269 .paintProperties() | 270 .paintProperties() |
| 270 ->localBorderBoxProperties() | 271 ->localBorderBoxProperties() |
| 271 ->transform(); | 272 ->transform(); |
| 272 | 273 |
| 273 FloatRect localRect(rectToMap); | 274 FloatRect floatRect(rectToMap); |
| 274 localRect.moveBy(FloatPoint(m_layer.layoutObject().paintOffset())); | 275 floatRect.moveBy(FloatPoint(m_layer.layoutObject().paintOffset())); |
| 275 rectToMap = LayoutRect(m_geometryMapper->sourceToDestinationRect( | 276 m_geometryMapper->sourceToDestinationRect(layerTransform, rootTransform, |
| 276 localRect, layerTransform, rootTransform)); | 277 floatRect); |
| 278 rectToMap = LayoutRect(floatRect); |
| 277 rectToMap.moveBy(-context.rootLayer->layoutObject().paintOffset()); | 279 rectToMap.moveBy(-context.rootLayer->layoutObject().paintOffset()); |
| 278 rectToMap.move(context.subPixelAccumulation); | 280 rectToMap.move(context.subPixelAccumulation); |
| 279 } | 281 } |
| 280 | 282 |
| 281 void PaintLayerClipper::calculateRectsWithGeometryMapper( | 283 void PaintLayerClipper::calculateRectsWithGeometryMapper( |
| 282 const ClipRectsContext& context, | 284 const ClipRectsContext& context, |
| 283 const LayoutRect& paintDirtyRect, | 285 const LayoutRect& paintDirtyRect, |
| 284 LayoutRect& layerBounds, | 286 LayoutRect& layerBounds, |
| 285 ClipRect& backgroundRect, | 287 ClipRect& backgroundRect, |
| 286 ClipRect& foregroundRect, | 288 ClipRect& foregroundRect, |
| 287 const LayoutPoint* offsetFromRoot) const { | 289 const LayoutPoint* offsetFromRoot) const { |
| 288 const auto* properties = m_layer.layoutObject().paintProperties(); | 290 const auto* properties = m_layer.layoutObject().paintProperties(); |
| 289 // TODO(chrishtr): fix the underlying bug that causes this situation. | 291 // TODO(chrishtr): fix the underlying bug that causes this situation. |
| 290 if (!properties) { | 292 if (!properties) { |
| 291 backgroundRect = ClipRect(LayoutRect(LayoutRect::infiniteIntRect())); | 293 backgroundRect = ClipRect(LayoutRect(LayoutRect::infiniteIntRect())); |
| 292 foregroundRect = ClipRect(LayoutRect(LayoutRect::infiniteIntRect())); | 294 foregroundRect = ClipRect(LayoutRect(LayoutRect::infiniteIntRect())); |
| 293 } else { | 295 } else { |
| 294 backgroundRect = clipRectWithGeometryMapper(context, false); | 296 calculateClipRectWithGeometryMapper(context, false, backgroundRect); |
| 295 | 297 |
| 296 backgroundRect.move(context.subPixelAccumulation); | 298 backgroundRect.move(context.subPixelAccumulation); |
| 297 backgroundRect.intersect(paintDirtyRect); | 299 backgroundRect.intersect(paintDirtyRect); |
| 298 | 300 |
| 299 applyOverflowClipToBackgroundRectWithGeometryMapper(context, | 301 applyOverflowClipToBackgroundRectWithGeometryMapper(context, |
| 300 backgroundRect); | 302 backgroundRect); |
| 301 | 303 |
| 302 foregroundRect = clipRectWithGeometryMapper(context, true); | 304 calculateClipRectWithGeometryMapper(context, true, foregroundRect); |
| 303 foregroundRect.move(context.subPixelAccumulation); | 305 foregroundRect.move(context.subPixelAccumulation); |
| 304 foregroundRect.intersect(paintDirtyRect); | 306 foregroundRect.intersect(paintDirtyRect); |
| 305 } | 307 } |
| 306 LayoutPoint offset; | 308 LayoutPoint offset; |
| 307 if (offsetFromRoot) | 309 if (offsetFromRoot) |
| 308 offset = *offsetFromRoot; | 310 offset = *offsetFromRoot; |
| 309 else | 311 else |
| 310 m_layer.convertToLayerCoords(context.rootLayer, offset); | 312 m_layer.convertToLayerCoords(context.rootLayer, offset); |
| 311 layerBounds = LayoutRect(offset, LayoutSize(m_layer.size())); | 313 layerBounds = LayoutRect(offset, LayoutSize(m_layer.size())); |
| 312 | 314 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 333 calculateRectsWithGeometryMapper(context, paintDirtyRect, layerBounds, | 335 calculateRectsWithGeometryMapper(context, paintDirtyRect, layerBounds, |
| 334 backgroundRect, foregroundRect, | 336 backgroundRect, foregroundRect, |
| 335 offsetFromRoot); | 337 offsetFromRoot); |
| 336 return; | 338 return; |
| 337 } | 339 } |
| 338 | 340 |
| 339 bool isClippingRoot = &m_layer == context.rootLayer; | 341 bool isClippingRoot = &m_layer == context.rootLayer; |
| 340 LayoutBoxModelObject& layoutObject = m_layer.layoutObject(); | 342 LayoutBoxModelObject& layoutObject = m_layer.layoutObject(); |
| 341 | 343 |
| 342 if (!isClippingRoot && m_layer.parent()) { | 344 if (!isClippingRoot && m_layer.parent()) { |
| 343 backgroundRect = backgroundClipRect(context); | 345 calculateBackgroundClipRect(context, backgroundRect); |
| 344 backgroundRect.move(context.subPixelAccumulation); | 346 backgroundRect.move(context.subPixelAccumulation); |
| 345 backgroundRect.intersect(paintDirtyRect); | 347 backgroundRect.intersect(paintDirtyRect); |
| 346 } else { | 348 } else { |
| 347 backgroundRect = paintDirtyRect; | 349 backgroundRect = paintDirtyRect; |
| 348 } | 350 } |
| 349 | 351 |
| 350 foregroundRect = backgroundRect; | 352 foregroundRect = backgroundRect; |
| 351 | 353 |
| 352 LayoutPoint offset; | 354 LayoutPoint offset; |
| 353 if (offsetFromRoot) | 355 if (offsetFromRoot) |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 EPosition position) { | 436 EPosition position) { |
| 435 if (position == EPosition::kFixed) | 437 if (position == EPosition::kFixed) |
| 436 return parentRects.fixedClipRect(); | 438 return parentRects.fixedClipRect(); |
| 437 | 439 |
| 438 if (position == EPosition::kAbsolute) | 440 if (position == EPosition::kAbsolute) |
| 439 return parentRects.posClipRect(); | 441 return parentRects.posClipRect(); |
| 440 | 442 |
| 441 return parentRects.overflowClipRect(); | 443 return parentRects.overflowClipRect(); |
| 442 } | 444 } |
| 443 | 445 |
| 444 ClipRect PaintLayerClipper::clipRectWithGeometryMapper( | 446 void PaintLayerClipper::calculateClipRectWithGeometryMapper( |
| 445 const ClipRectsContext& context, | 447 const ClipRectsContext& context, |
| 446 bool isForeground) const { | 448 bool isForeground, |
| 449 ClipRect& output) const { |
| 447 DCHECK(m_geometryMapper); | 450 DCHECK(m_geometryMapper); |
| 448 const auto* properties = m_layer.layoutObject().paintProperties(); | 451 const auto* properties = m_layer.layoutObject().paintProperties(); |
| 449 DCHECK(properties && properties->localBorderBoxProperties()); | 452 DCHECK(properties && properties->localBorderBoxProperties()); |
| 450 | 453 |
| 451 PropertyTreeState propertyTreeState = *properties->localBorderBoxProperties(); | 454 PropertyTreeState propertyTreeState = *properties->localBorderBoxProperties(); |
| 452 const auto* ancestorProperties = | 455 const auto* ancestorProperties = |
| 453 context.rootLayer->layoutObject().paintProperties(); | 456 context.rootLayer->layoutObject().paintProperties(); |
| 454 DCHECK(ancestorProperties && ancestorProperties->localBorderBoxProperties()); | 457 DCHECK(ancestorProperties && ancestorProperties->localBorderBoxProperties()); |
| 455 PropertyTreeState destinationPropertyTreeState = | 458 PropertyTreeState destinationPropertyTreeState = |
| 456 *ancestorProperties->localBorderBoxProperties(); | 459 *ancestorProperties->localBorderBoxProperties(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 467 if (context.respectOverflowClip == IgnoreOverflowClip && | 470 if (context.respectOverflowClip == IgnoreOverflowClip && |
| 468 ancestorProperties->overflowClip()) | 471 ancestorProperties->overflowClip()) |
| 469 destinationPropertyTreeState.setClip(ancestorProperties->overflowClip()); | 472 destinationPropertyTreeState.setClip(ancestorProperties->overflowClip()); |
| 470 | 473 |
| 471 // Set the overflow clip for |propertyTreeState| so that it differs from | 474 // Set the overflow clip for |propertyTreeState| so that it differs from |
| 472 // destinationPropertyTreeState| in its clip. | 475 // destinationPropertyTreeState| in its clip. |
| 473 if (isForeground && properties->overflowClip()) | 476 if (isForeground && properties->overflowClip()) |
| 474 propertyTreeState.setClip(properties->overflowClip()); | 477 propertyTreeState.setClip(properties->overflowClip()); |
| 475 } | 478 } |
| 476 | 479 |
| 477 FloatClipRect clippedRectInRootLayerSpace = | 480 const FloatClipRect& clippedRectInRootLayerSpace = |
| 478 m_geometryMapper->sourceToDestinationClipRect( | 481 m_geometryMapper->sourceToDestinationClipRect( |
| 479 propertyTreeState, destinationPropertyTreeState); | 482 propertyTreeState, destinationPropertyTreeState); |
| 480 ClipRect clipRect(LayoutRect(clippedRectInRootLayerSpace.rect())); | 483 output.setRect(clippedRectInRootLayerSpace); |
| 481 if (clippedRectInRootLayerSpace.hasRadius()) | |
| 482 clipRect.setHasRadius(true); | |
| 483 | 484 |
| 484 clipRect.moveBy(-context.rootLayer->layoutObject().paintOffset()); | 485 output.moveBy(-context.rootLayer->layoutObject().paintOffset()); |
| 485 return clipRect; | |
| 486 } | 486 } |
| 487 | 487 |
| 488 void PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper( | 488 void PaintLayerClipper::applyOverflowClipToBackgroundRectWithGeometryMapper( |
| 489 const ClipRectsContext& context, | 489 const ClipRectsContext& context, |
| 490 ClipRect& clip) const { | 490 ClipRect& clip) const { |
| 491 const LayoutObject& layoutObject = m_layer.layoutObject(); | 491 const LayoutObject& layoutObject = m_layer.layoutObject(); |
| 492 if (!shouldClipOverflow(context)) | 492 if (!shouldClipOverflow(context)) |
| 493 return; | 493 return; |
| 494 LayoutRect layerBoundsWithVisualOverflow = | 494 LayoutRect layerBoundsWithVisualOverflow = |
| 495 layoutObject.isLayoutView() | 495 layoutObject.isLayoutView() |
| 496 ? toLayoutView(layoutObject).viewRect() | 496 ? toLayoutView(layoutObject).viewRect() |
| 497 : toLayoutBox(layoutObject).visualOverflowRect(); | 497 : toLayoutBox(layoutObject).visualOverflowRect(); |
| 498 toLayoutBox(layoutObject) | 498 toLayoutBox(layoutObject) |
| 499 .flipForWritingMode( | 499 .flipForWritingMode( |
| 500 // PaintLayer are in physical coordinates, so the overflow has to be | 500 // PaintLayer are in physical coordinates, so the overflow has to be |
| 501 // flipped. | 501 // flipped. |
| 502 layerBoundsWithVisualOverflow); | 502 layerBoundsWithVisualOverflow); |
| 503 mapLocalToRootWithGeometryMapper(context, layerBoundsWithVisualOverflow); | 503 mapLocalToRootWithGeometryMapper(context, layerBoundsWithVisualOverflow); |
| 504 clip.intersect(layerBoundsWithVisualOverflow); | 504 clip.intersect(layerBoundsWithVisualOverflow); |
| 505 } | 505 } |
| 506 | 506 |
| 507 ClipRect PaintLayerClipper::backgroundClipRect( | 507 void PaintLayerClipper::calculateBackgroundClipRect( |
| 508 const ClipRectsContext& context) const { | 508 const ClipRectsContext& context, |
| 509 ClipRect& output) const { |
| 509 if (m_geometryMapper) { | 510 if (m_geometryMapper) { |
| 510 // TODO(chrishtr): fix the underlying bug that causes this situation. | 511 // TODO(chrishtr): fix the underlying bug that causes this situation. |
| 511 if (!m_layer.layoutObject().paintProperties()) | 512 if (!m_layer.layoutObject().paintProperties()) { |
| 512 return ClipRect(LayoutRect(LayoutRect::infiniteIntRect())); | 513 output.setRect(FloatClipRect()); |
| 514 return; |
| 515 } |
| 513 | 516 |
| 514 ClipRect backgroundClipRect = clipRectWithGeometryMapper(context, false); | 517 calculateClipRectWithGeometryMapper(context, false, output); |
| 515 #ifdef CHECK_CLIP_RECTS | 518 #ifdef CHECK_CLIP_RECTS |
| 516 ClipRect testBackgroundClipRect = | 519 ClipRect testBackgroundClipRect = |
| 517 PaintLayerClipper(m_layer, nullptr).backgroundClipRect(context); | 520 PaintLayerClipper(m_layer, nullptr).backgroundClipRect(context); |
| 518 CHECK_RECTS_EQ(testBackgroundClipRect, backgroundClipRect); | 521 CHECK_RECTS_EQ(testBackgroundClipRect, output); |
| 519 #endif | 522 #endif |
| 520 return backgroundClipRect; | 523 return; |
| 521 } | 524 } |
| 522 DCHECK(m_layer.parent()); | 525 DCHECK(m_layer.parent()); |
| 523 LayoutView* layoutView = m_layer.layoutObject().view(); | 526 LayoutView* layoutView = m_layer.layoutObject().view(); |
| 524 DCHECK(layoutView); | 527 DCHECK(layoutView); |
| 525 | 528 |
| 526 RefPtr<ClipRects> parentClipRects = ClipRects::create(); | 529 RefPtr<ClipRects> parentClipRects = ClipRects::create(); |
| 527 if (&m_layer == context.rootLayer) { | 530 if (&m_layer == context.rootLayer) { |
| 528 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); | 531 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 529 } else { | 532 } else { |
| 530 PaintLayerClipper(*m_layer.parent(), m_geometryMapper) | 533 PaintLayerClipper(*m_layer.parent(), m_geometryMapper) |
| 531 .getOrCalculateClipRects(context, *parentClipRects); | 534 .getOrCalculateClipRects(context, *parentClipRects); |
| 532 } | 535 } |
| 533 | 536 |
| 534 ClipRect result = backgroundClipRectForPosition( | 537 output = backgroundClipRectForPosition( |
| 535 *parentClipRects, m_layer.layoutObject().styleRef().position()); | 538 *parentClipRects, m_layer.layoutObject().styleRef().position()); |
| 536 | 539 |
| 537 // Note: infinite clipRects should not be scrolled here, otherwise they will | 540 // Note: infinite clipRects should not be scrolled here, otherwise they will |
| 538 // accidentally no longer be considered infinite. | 541 // accidentally no longer be considered infinite. |
| 539 if (parentClipRects->fixed() && | 542 if (parentClipRects->fixed() && |
| 540 &context.rootLayer->layoutObject() == layoutView && | 543 &context.rootLayer->layoutObject() == layoutView && |
| 541 result != LayoutRect(LayoutRect::infiniteIntRect())) | 544 output != LayoutRect(LayoutRect::infiniteIntRect())) |
| 542 result.move(LayoutSize(layoutView->frameView()->getScrollOffset())); | 545 output.move(LayoutSize(layoutView->frameView()->getScrollOffset())); |
| 543 | |
| 544 return result; | |
| 545 } | 546 } |
| 546 | 547 |
| 547 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, | 548 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, |
| 548 ClipRects& clipRects) const { | 549 ClipRects& clipRects) const { |
| 549 DCHECK(!m_geometryMapper); | 550 DCHECK(!m_geometryMapper); |
| 550 | 551 |
| 551 if (context.usesCache()) | 552 if (context.usesCache()) |
| 552 clipRects = getClipRects(context); | 553 clipRects = getClipRects(context); |
| 553 else | 554 else |
| 554 calculateClipRects(context, clipRects); | 555 calculateClipRects(context, clipRects); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 const LayoutSize& subpixelAccumulation) const { | 588 const LayoutSize& subpixelAccumulation) const { |
| 588 DCHECK(!m_geometryMapper); | 589 DCHECK(!m_geometryMapper); |
| 589 ClipRectsContext context(rootLayer, PaintingClipRects, | 590 ClipRectsContext context(rootLayer, PaintingClipRects, |
| 590 IgnoreOverlayScrollbarSize, subpixelAccumulation); | 591 IgnoreOverlayScrollbarSize, subpixelAccumulation); |
| 591 if (respectOverflowClip == IgnoreOverflowClip) | 592 if (respectOverflowClip == IgnoreOverflowClip) |
| 592 context.setIgnoreOverflowClip(); | 593 context.setIgnoreOverflowClip(); |
| 593 return getClipRects(context); | 594 return getClipRects(context); |
| 594 } | 595 } |
| 595 | 596 |
| 596 } // namespace blink | 597 } // namespace blink |
| OLD | NEW |