Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(420)

Side by Side Diff: Source/core/rendering/RenderBox.cpp

Issue 102123013: Fix painting of fixed background images in composited layers (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) 3 * (C) 1999 Antti Koivisto (koivisto@kde.org)
4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com) 4 * (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com) 5 * (C) 2005, 2006 Samuel Weinig (sam.weinig@gmail.com)
6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed. 6 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserv ed.
7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved. 7 * Copyright (C) 2013 Adobe Systems Incorporated. All rights reserved.
8 * 8 *
9 * This library is free software; you can redistribute it and/or 9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public 10 * modify it under the terms of the GNU Library General Public
(...skipping 1313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 paintRootBoxFillLayers(paintInfo); 1324 paintRootBoxFillLayers(paintInfo);
1325 return; 1325 return;
1326 } 1326 }
1327 if (isBody() && skipBodyBackground(this)) 1327 if (isBody() && skipBodyBackground(this))
1328 return; 1328 return;
1329 if (backgroundIsKnownToBeObscured()) 1329 if (backgroundIsKnownToBeObscured())
1330 return; 1330 return;
1331 paintFillLayers(paintInfo, resolveColor(CSSPropertyBackgroundColor), style() ->backgroundLayers(), paintRect, bleedAvoidance); 1331 paintFillLayers(paintInfo, resolveColor(CSSPropertyBackgroundColor), style() ->backgroundLayers(), paintRect, bleedAvoidance);
1332 } 1332 }
1333 1333
1334 LayoutRect RenderBox::backgroundPaintedExtent() const 1334 bool RenderBox::getBackgroundPaintedExtent(LayoutRect& paintedExtent) const
1335 { 1335 {
1336 ASSERT(hasBackground()); 1336 ASSERT(hasBackground());
1337 LayoutRect backgroundRect = pixelSnappedIntRect(borderBoxRect()); 1337 LayoutRect backgroundRect = pixelSnappedIntRect(borderBoxRect());
1338 1338
1339 Color backgroundColor = resolveColor(CSSPropertyBackgroundColor); 1339 Color backgroundColor = resolveColor(CSSPropertyBackgroundColor);
1340 if (backgroundColor.isValid() && backgroundColor.alpha()) 1340 if (backgroundColor.isValid() && backgroundColor.alpha()) {
1341 return backgroundRect; 1341 paintedExtent = backgroundRect;
1342 if (!style()->backgroundLayers()->image() || style()->backgroundLayers()->ne xt()) 1342 return true;
1343 return backgroundRect; 1343 }
1344
1345 if (!style()->backgroundLayers()->image() || style()->backgroundLayers()->ne xt()) {
1346 paintedExtent = backgroundRect;
1347 return true;
1348 }
1349
1344 BackgroundImageGeometry geometry; 1350 BackgroundImageGeometry geometry;
1345 const_cast<RenderBox*>(this)->calculateBackgroundImageGeometry(style()->back groundLayers(), backgroundRect, geometry); 1351 calculateBackgroundImageGeometry(0, style()->backgroundLayers(), backgroundR ect, geometry);
1346 return geometry.destRect(); 1352 paintedExtent = geometry.destRect();
1353 return !geometry.hasNonLocalGeometry();
esprehn 2014/01/08 01:53:55 Instead of assigning the values of the layout rect
Stephen White 2014/03/27 15:07:12 Done.
1347 } 1354 }
1348 1355
1349 bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) c onst 1356 bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) c onst
1350 { 1357 {
1351 if (isBody() && skipBodyBackground(this)) 1358 if (isBody() && skipBodyBackground(this))
1352 return false; 1359 return false;
1353 1360
1354 Color backgroundColor = resolveColor(CSSPropertyBackgroundColor); 1361 Color backgroundColor = resolveColor(CSSPropertyBackgroundColor);
1355 if (!backgroundColor.isValid() || backgroundColor.hasAlpha()) 1362 if (!backgroundColor.isValid() || backgroundColor.hasAlpha())
1356 return false; 1363 return false;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1446 // Test to see if the children trivially obscure the background. 1453 // Test to see if the children trivially obscure the background.
1447 // FIXME: This test can be much more comprehensive. 1454 // FIXME: This test can be much more comprehensive.
1448 if (!hasBackground()) 1455 if (!hasBackground())
1449 return false; 1456 return false;
1450 // Table and root background painting is special. 1457 // Table and root background painting is special.
1451 if (isTable() || isRoot()) 1458 if (isTable() || isRoot())
1452 return false; 1459 return false;
1453 // FIXME: box-shadow is painted while background painting. 1460 // FIXME: box-shadow is painted while background painting.
1454 if (style()->boxShadow()) 1461 if (style()->boxShadow())
1455 return false; 1462 return false;
1456 LayoutRect backgroundRect = backgroundPaintedExtent(); 1463 LayoutRect backgroundRect;
1464 if (!getBackgroundPaintedExtent(backgroundRect))
1465 return false;
1457 return foregroundIsKnownToBeOpaqueInRect(backgroundRect, backgroundObscurati onTestMaxDepth); 1466 return foregroundIsKnownToBeOpaqueInRect(backgroundRect, backgroundObscurati onTestMaxDepth);
1458 } 1467 }
1459 1468
1460 bool RenderBox::backgroundHasOpaqueTopLayer() const 1469 bool RenderBox::backgroundHasOpaqueTopLayer() const
1461 { 1470 {
1462 const FillLayer* fillLayer = style()->backgroundLayers(); 1471 const FillLayer* fillLayer = style()->backgroundLayers();
1463 if (!fillLayer || fillLayer->clip() != BorderFillBox) 1472 if (!fillLayer || fillLayer->clip() != BorderFillBox)
1464 return false; 1473 return false;
1465 1474
1466 // Clipped with local scrolling 1475 // Clipped with local scrolling
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1550 // Apply outsets to the border box. 1559 // Apply outsets to the border box.
1551 borderImageRect.expand(style()->maskBoxImageOutsets()); 1560 borderImageRect.expand(style()->maskBoxImageOutsets());
1552 return borderImageRect; 1561 return borderImageRect;
1553 } 1562 }
1554 1563
1555 LayoutRect result; 1564 LayoutRect result;
1556 LayoutRect borderBox = borderBoxRect(); 1565 LayoutRect borderBox = borderBoxRect();
1557 for (const FillLayer* maskLayer = style()->maskLayers(); maskLayer; maskLaye r = maskLayer->next()) { 1566 for (const FillLayer* maskLayer = style()->maskLayers(); maskLayer; maskLaye r = maskLayer->next()) {
1558 if (maskLayer->image()) { 1567 if (maskLayer->image()) {
1559 BackgroundImageGeometry geometry; 1568 BackgroundImageGeometry geometry;
1560 calculateBackgroundImageGeometry(maskLayer, borderBox, geometry); 1569 // Masks should never have fixed attachment, so it's OK for paintCon tainer to be null.
1570 calculateBackgroundImageGeometry(0, maskLayer, borderBox, geometry);
1561 result.unite(geometry.destRect()); 1571 result.unite(geometry.destRect());
1562 } 1572 }
1563 } 1573 }
1564 return result; 1574 return result;
1565 } 1575 }
1566 1576
1567 void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, cons t FillLayer* fillLayer, const LayoutRect& rect, 1577 void RenderBox::paintFillLayers(const PaintInfo& paintInfo, const Color& c, cons t FillLayer* fillLayer, const LayoutRect& rect,
1568 BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderObject* backgroundObject) 1578 BackgroundBleedAvoidance bleedAvoidance, CompositeOperator op, RenderObject* backgroundObject)
1569 { 1579 {
1570 Vector<const FillLayer*, 8> layers; 1580 Vector<const FillLayer*, 8> layers;
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 layer()->contentChanged(MaskImageChanged); 1649 layer()->contentChanged(MaskImageChanged);
1640 } 1650 }
1641 1651
1642 bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer * layers, bool drawingBackground) 1652 bool RenderBox::repaintLayerRectsForImage(WrappedImagePtr image, const FillLayer * layers, bool drawingBackground)
1643 { 1653 {
1644 LayoutRect rendererRect; 1654 LayoutRect rendererRect;
1645 RenderBox* layerRenderer = 0; 1655 RenderBox* layerRenderer = 0;
1646 1656
1647 for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next ()) { 1657 for (const FillLayer* curLayer = layers; curLayer; curLayer = curLayer->next ()) {
1648 if (curLayer->image() && image == curLayer->image()->data() && curLayer- >image()->canRender(this, style()->effectiveZoom())) { 1658 if (curLayer->image() && image == curLayer->image()->data() && curLayer- >image()->canRender(this, style()->effectiveZoom())) {
1649 // Now that we know this image is being used, compute the renderer a nd the rect 1659 // Now that we know this image is being used, compute the renderer a nd the rect if we haven't already.
1650 // if we haven't already
1651 if (!layerRenderer) { 1660 if (!layerRenderer) {
1652 bool drawingRootBackground = drawingBackground && (isRoot() || ( isBody() && !document().documentElement()->renderer()->hasBackground())); 1661 bool drawingRootBackground = drawingBackground && (isRoot() || ( isBody() && !document().documentElement()->renderer()->hasBackground()));
1653 if (drawingRootBackground) { 1662 if (drawingRootBackground) {
1654 layerRenderer = view(); 1663 layerRenderer = view();
1655 1664
1656 LayoutUnit rw; 1665 LayoutUnit rw;
1657 LayoutUnit rh; 1666 LayoutUnit rh;
1658 1667
1659 if (FrameView* frameView = toRenderView(layerRenderer)->fram eView()) { 1668 if (FrameView* frameView = toRenderView(layerRenderer)->fram eView()) {
1660 rw = frameView->contentsWidth(); 1669 rw = frameView->contentsWidth();
1661 rh = frameView->contentsHeight(); 1670 rh = frameView->contentsHeight();
1662 } else { 1671 } else {
1663 rw = layerRenderer->width(); 1672 rw = layerRenderer->width();
1664 rh = layerRenderer->height(); 1673 rh = layerRenderer->height();
1665 } 1674 }
1666 rendererRect = LayoutRect(-layerRenderer->marginLeft(), 1675 rendererRect = LayoutRect(-layerRenderer->marginLeft(),
1667 -layerRenderer->marginTop(), 1676 -layerRenderer->marginTop(),
1668 max(layerRenderer->width() + layerRenderer->marginWidth( ) + layerRenderer->borderLeft() + layerRenderer->borderRight(), rw), 1677 max(layerRenderer->width() + layerRenderer->marginWidth( ) + layerRenderer->borderLeft() + layerRenderer->borderRight(), rw),
1669 max(layerRenderer->height() + layerRenderer->marginHeigh t() + layerRenderer->borderTop() + layerRenderer->borderBottom(), rh)); 1678 max(layerRenderer->height() + layerRenderer->marginHeigh t() + layerRenderer->borderTop() + layerRenderer->borderBottom(), rh));
1670 } else { 1679 } else {
1671 layerRenderer = this; 1680 layerRenderer = this;
1672 rendererRect = borderBoxRect(); 1681 rendererRect = borderBoxRect();
1673 } 1682 }
1674 } 1683 }
1675 1684
1676 BackgroundImageGeometry geometry; 1685 BackgroundImageGeometry geometry;
1677 layerRenderer->calculateBackgroundImageGeometry(curLayer, rendererRe ct, geometry); 1686 layerRenderer->calculateBackgroundImageGeometry(0, curLayer, rendere rRect, geometry);
1687 if (geometry.hasNonLocalGeometry()) {
1688 // Rather than incur the costs of computing the paintContainer f or renderers with fixed backgrounds
1689 // in order to get the right destRect, just repaint the entire r enderer.
1690 layerRenderer->repaint();
esprehn 2014/01/08 01:53:55 I suspect this will be far worse sometimes too, a
Stephen White 2014/03/27 15:07:12 I defer to someone more knowledgeable. I'm just ca
1691 return true;
1692 }
1693
1678 layerRenderer->repaintRectangle(geometry.destRect()); 1694 layerRenderer->repaintRectangle(geometry.destRect());
1679 if (geometry.destRect() == rendererRect) 1695 if (geometry.destRect() == rendererRect)
1680 return true; 1696 return true;
1681 } 1697 }
1682 } 1698 }
1683 return false; 1699 return false;
1684 } 1700 }
1685 1701
1686 bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu latedOffset, ContentsClipBehavior contentsClipBehavior) 1702 bool RenderBox::pushContentsClip(PaintInfo& paintInfo, const LayoutPoint& accumu latedOffset, ContentsClipBehavior contentsClipBehavior)
1687 { 1703 {
(...skipping 3262 matching lines...) Expand 10 before | Expand all | Expand 10 after
4950 return 0; 4966 return 0;
4951 4967
4952 if (!layoutState && !flowThreadContainingBlock()) 4968 if (!layoutState && !flowThreadContainingBlock())
4953 return 0; 4969 return 0;
4954 4970
4955 RenderBlock* containerBlock = containingBlock(); 4971 RenderBlock* containerBlock = containingBlock();
4956 return containerBlock->offsetFromLogicalTopOfFirstPage() + logicalTop(); 4972 return containerBlock->offsetFromLogicalTopOfFirstPage() + logicalTop();
4957 } 4973 }
4958 4974
4959 } // namespace WebCore 4975 } // namespace WebCore
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698