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 |