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