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 |