1bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)/* 2bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. 3bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 4bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Portions are Copyright (C) 1998 Netscape Communications Corporation. 5bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 6bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Other contributors: 7bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Robert O'Callahan <roc+@cs.cmu.edu> 8bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * David Baron <dbaron@fas.harvard.edu> 9bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Christian Biesinger <cbiesinger@web.de> 10bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Randall Jesup <rjesup@wgate.com> 11bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> 12bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Josh Soref <timeless@mac.com> 13bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Boris Zbarsky <bzbarsky@mit.edu> 14bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 15bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * This library is free software; you can redistribute it and/or 16bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * modify it under the terms of the GNU Lesser General Public 17bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * License as published by the Free Software Foundation; either 18bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * version 2.1 of the License, or (at your option) any later version. 19bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 20bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 21bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 22bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 23bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Lesser General Public License for more details. 24bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 25bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * You should have received a copy of the GNU Lesser General Public 26bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * License along with this library; if not, write to the Free Software 27bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 28bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * 29bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * Alternatively, the contents of this file may be used under the terms 30bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * of either the Mozilla Public License Version 1.1, found at 31bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public 32bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html 33bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * (the "GPL"), in which case the provisions of the MPL or the GPL are 34bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * applicable instead of those above. If you wish to allow use of your 35bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * version of this file only under the terms of one of those two 36bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * licenses (the MPL or the GPL) and not to allow others to use your 37bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * version of this file under the LGPL, indicate your decision by 38bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * deletingthe provisions above and replace them with the notice and 39bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * other provisions required by the MPL or the GPL, as the case may be. 40bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * If you do not delete the provisions above, a recipient may use your 41bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) * version of this file under any of the LGPL, the MPL or the GPL. 42bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) */ 43bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 44bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "config.h" 45bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/rendering/RenderLayerClipper.h" 46bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 47bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/rendering/RenderLayer.h" 48bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#include "core/rendering/RenderView.h" 49bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 50c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink { 51bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 52197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic void adjustClipRectsForChildren(const RenderObject& renderer, ClipRects& clipRects) 53bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 54197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch EPosition position = renderer.style()->position(); 55197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // A fixed object is essentially the root of its containing block hierarchy, so when 56197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // we encounter such an object, we reset our clip rects to the fixedClipRect. 57197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (position == FixedPosition) { 58197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setPosClipRect(clipRects.fixedClipRect()); 59197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setOverflowClipRect(clipRects.fixedClipRect()); 60197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setFixed(true); 61197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } else if (position == RelativePosition) { 62197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setPosClipRect(clipRects.overflowClipRect()); 63197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } else if (position == AbsolutePosition) { 64197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setOverflowClipRect(clipRects.posClipRect()); 65197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 66197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 67bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 68197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic void applyClipRects(const ClipRectsContext& context, RenderObject& renderer, LayoutPoint offset, ClipRects& clipRects) 69197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 70197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(renderer.hasOverflowClip() || renderer.hasClip()); 71197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 72197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch RenderView* view = renderer.view(); 73197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(view); 74197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (clipRects.fixed() && context.rootLayer->renderer() == view) 75197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch offset -= view->frameView()->scrollOffsetForFixedPosition(); 76197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (renderer.hasOverflowClip()) { 78197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRect newOverflowClip = toRenderBox(renderer).overflowClipRect(offset, context.scrollbarRelevancy); 79197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch newOverflowClip.setHasRadius(renderer.style()->hasBorderRadius()); 80197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect())); 81197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (renderer.isPositioned()) 82197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect())); 83bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 84bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 85197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (renderer.hasClip()) { 86197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch LayoutRect newClip = toRenderBox(renderer).clipRect(offset); 87197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect())); 88197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowClipRect())); 89197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect())); 90197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 91197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 92bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 93197021e6b966cfb06891637935ef33fff06433d1Ben MurdochRenderLayerClipper::RenderLayerClipper(RenderLayerModelObject& renderer) 94197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch : m_renderer(renderer) 95197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 96197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 97bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 98197021e6b966cfb06891637935ef33fff06433d1Ben MurdochClipRects* RenderLayerClipper::clipRectsIfCached(const ClipRectsContext& context) const 99197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(context.usesCache()); 101197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!m_cache) 102197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return 0; 103197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRectsCache::Entry& entry = m_cache->get(context.cacheSlot); 104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // FIXME: We used to ASSERT that we always got a consistent root layer. 105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // We should add a test that has an inconsistent root. See 106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // http://crbug.com/366118 for an example. 107197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (context.rootLayer != entry.root) 108197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return 0; 109197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(entry.scrollbarRelevancy == context.scrollbarRelevancy); 110bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 111197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#ifdef CHECK_CACHED_CLIP_RECTS 112197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default. 113197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRectsContext tempContext(context); 114197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch tempContext.cacheSlot = UncachedClipRects; 115197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRects clipRects; 116197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch calculateClipRects(tempContext, clipRects); 117197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(clipRects == *entry.clipRects); 118197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#endif 119197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 120197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return entry.clipRects.get(); 121197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 122bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 123197021e6b966cfb06891637935ef33fff06433d1Ben MurdochClipRects* RenderLayerClipper::storeClipRectsInCache(const ClipRectsContext& context, ClipRects* parentClipRects, const ClipRects& clipRects) const 124197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 125197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRectsCache::Entry& entry = cache().get(context.cacheSlot); 126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch entry.root = context.rootLayer; 127197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#if ENABLE(ASSERT) 128197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch entry.scrollbarRelevancy = context.scrollbarRelevancy; 129bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)#endif 130197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 131197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (parentClipRects) { 132197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // If our clip rects match the clip rects of our parent, we share storage. 133197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (clipRects == *parentClipRects) { 134197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch entry.clipRects = parentClipRects; 135197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return parentClipRects; 136197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 137197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch } 138197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 139197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch entry.clipRects = ClipRects::create(clipRects); 140197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return entry.clipRects.get(); 141bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 142bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 143197021e6b966cfb06891637935ef33fff06433d1Ben MurdochClipRects* RenderLayerClipper::getClipRects(const ClipRectsContext& context) const 144197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{ 145197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (ClipRects* result = clipRectsIfCached(context)) 146197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return result; 147197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 148197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Note that it's important that we call getClipRects on our parent 149197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // before we call calculateClipRects so that calculateClipRects will hit 150197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // the cache. 151197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRects* parentClipRects = 0; 152197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (context.rootLayer != m_renderer.layer() && m_renderer.layer()->parent()) 153197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch parentClipRects = m_renderer.layer()->parent()->clipper().getClipRects(context); 154197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 155197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRects clipRects; 156197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch calculateClipRects(context, clipRects); 157197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return storeClipRectsInCache(context, parentClipRects, clipRects); 158197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch} 159197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 160197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderLayerClipper::clearClipRectsIncludingDescendants() 161bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 162197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_cache = nullptr; 163bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 164f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu for (RenderLayer* layer = m_renderer.layer()->firstChild(); layer; layer = layer->nextSibling()) 165197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch layer->clipper().clearClipRectsIncludingDescendants(); 166bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 167bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 168197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCacheSlot cacheSlot) 169bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 1707242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci if (m_cache) 1717242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci m_cache->clear(cacheSlot); 172197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 173197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch for (RenderLayer* layer = m_renderer.layer()->firstChild(); layer; layer = layer->nextSibling()) 174197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); 175bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 176bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 17709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)LayoutRect RenderLayerClipper::childrenClipRect() const 17809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 17909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: border-radius not accounted for. 18009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: Regions not accounted for. 18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderLayer* clippingRootLayer = clippingRootForPainting(); 18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) LayoutRect layerBounds; 18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ClipRect backgroundRect, foregroundRect, outlineRect; 184197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // Need to use uncached clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>). 185197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRectsContext context(clippingRootLayer, UncachedClipRects); 186197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch calculateRects(context, m_renderer.view()->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect); 18709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox(); 18809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 18909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 19009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)LayoutRect RenderLayerClipper::localClipRect() const 19109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 19209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: border-radius not accounted for. 19309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RenderLayer* clippingRootLayer = clippingRootForPainting(); 19409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) LayoutRect layerBounds; 19509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ClipRect backgroundRect, foregroundRect, outlineRect; 196197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRectsContext context(clippingRootLayer, PaintingClipRects); 197197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch calculateRects(context, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect); 19809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 19909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) LayoutRect clipRect = backgroundRect.rect(); 20009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (clipRect == PaintInfo::infiniteRect()) 20109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return clipRect; 20209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 20309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) LayoutPoint clippingRootOffset; 204f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu m_renderer.layer()->convertToLayerCoords(clippingRootLayer, clippingRootOffset); 20509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) clipRect.moveBy(-clippingRootOffset); 20609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 20709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return clipRect; 20809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 20909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 210197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderLayerClipper::calculateRects(const ClipRectsContext& context, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds, 21109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot) const 21209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 213197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool isClippingRoot = m_renderer.layer() == context.rootLayer; 21407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 215f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (!isClippingRoot && m_renderer.layer()->parent()) { 216197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch backgroundRect = backgroundClipRect(context); 217197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch backgroundRect.move(roundedIntSize(context.subPixelAccumulation)); 21809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) backgroundRect.intersect(paintDirtyRect); 21909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 22009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) backgroundRect = paintDirtyRect; 22109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 22209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 22309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) foregroundRect = backgroundRect; 22409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) outlineRect = backgroundRect; 22509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 22609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) LayoutPoint offset; 22709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (offsetFromRoot) 22809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) offset = *offsetFromRoot; 22909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) else 230197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_renderer.layer()->convertToLayerCoords(context.rootLayer, offset); 231f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu layerBounds = LayoutRect(offset, m_renderer.layer()->size()); 23209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 23309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Update the clip rects that will be passed to child layers. 234f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (m_renderer.hasOverflowClip()) { 23509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // This layer establishes a clip of some kind. 236197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!isClippingRoot || context.respectOverflowClip == RespectOverflowClip) { 237197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch foregroundRect.intersect(toRenderBox(m_renderer).overflowClipRect(offset, context.scrollbarRelevancy)); 238f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (m_renderer.style()->hasBorderRadius()) 23909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) foregroundRect.setHasRadius(true); 24009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 24109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 24209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // If we establish an overflow clip at all, then go ahead and make sure our background 24309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // rect is intersected with our layer's bounds including our visual overflow, 24409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden. 245f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (toRenderBox(m_renderer).hasVisualOverflow()) { 24609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though 24709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // we may need to inflate our clip specifically for shadows or outsets. 24809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the 24909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // individual region boxes as overflow. 250f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu LayoutRect layerBoundsWithVisualOverflow = toRenderBox(m_renderer).visualOverflowRect(); 251f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu toRenderBox(m_renderer).flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped. 25209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) layerBoundsWithVisualOverflow.moveBy(offset); 253197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!isClippingRoot || context.respectOverflowClip == RespectOverflowClip) 25409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) backgroundRect.intersect(layerBoundsWithVisualOverflow); 25509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } else { 256f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu LayoutRect bounds = toRenderBox(m_renderer).borderBoxRect(); 25709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) bounds.moveBy(offset); 258197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (!isClippingRoot || context.respectOverflowClip == RespectOverflowClip) 25909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) backgroundRect.intersect(bounds); 26009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 26109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 26209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 26309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box. 264f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (m_renderer.hasClip()) { 26509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Clip applies to *us* as well, so go ahead and update the damageRect. 266f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu LayoutRect newPosClip = toRenderBox(m_renderer).clipRect(offset); 26709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) backgroundRect.intersect(newPosClip); 26809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) foregroundRect.intersect(newPosClip); 26909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) outlineRect.intersect(newPosClip); 27009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 27109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 27209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 273197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderLayerClipper::calculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const 274bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles){ 275f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu if (!m_renderer.layer()->parent()) { 276bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // The root layer's clip rect is always infinite. 277bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) clipRects.reset(PaintInfo::infiniteRect()); 278bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) return; 279bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 280bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 281197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch bool isClippingRoot = m_renderer.layer() == context.rootLayer; 28207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch 283bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // For transformed layers, the root layer was shifted to be us, so there is no need to 284bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // examine the parent. We want to cache clip rects with us as the root. 285f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu RenderLayer* parentLayer = !isClippingRoot ? m_renderer.layer()->parent() : 0; 286bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 287bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // Ensure that our parent's clip has been calculated so that we can examine the values. 288bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) if (parentLayer) { 289197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // FIXME: Why don't we just call getClipRects here? 290197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (context.usesCache() && parentLayer->clipper().cachedClipRects(context)) { 291197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects = *parentLayer->clipper().cachedClipRects(context); 292bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } else { 293197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch parentLayer->clipper().calculateClipRects(context, clipRects); 294bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 295bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } else { 296bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) clipRects.reset(PaintInfo::infiniteRect()); 297bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 298bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 299197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch adjustClipRectsForChildren(m_renderer, clipRects); 300bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 301197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // FIXME: This logic looks wrong. We'll apply overflow clip rects even if we were told to IgnoreOverflowClip if m_renderer.hasClip(). 302197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if ((m_renderer.hasOverflowClip() && (context.respectOverflowClip == RespectOverflowClip || !isClippingRoot)) || m_renderer.hasClip()) { 303bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // This offset cannot use convertToLayerCoords, because sometimes our rootLayer may be across 304bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // some transformed layer boundary, for example, in the RenderLayerCompositor overlapMap, where 305bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) // clipRects are needed in view space. 306197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch applyClipRects(context, m_renderer, roundedLayoutPoint(m_renderer.localToContainerPoint(FloatPoint(), context.rootLayer->renderer())), clipRects); 307bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) } 308bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)} 309bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles) 310197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position) 31109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 31209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (position == FixedPosition) 31309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return parentRects.fixedClipRect(); 31409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 31509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (position == AbsolutePosition) 31609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return parentRects.posClipRect(); 31709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 31809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return parentRects.overflowClipRect(); 31909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 32009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 321197021e6b966cfb06891637935ef33fff06433d1Ben MurdochClipRect RenderLayerClipper::backgroundClipRect(const ClipRectsContext& context) const 32209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 323f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu ASSERT(m_renderer.layer()->parent()); 324197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ASSERT(m_renderer.view()); 32509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 326197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRects parentClipRects; 327197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (m_renderer.layer() == context.rootLayer) 328197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch parentClipRects.reset(PaintInfo::infiniteRect()); 329197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch else 330197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch m_renderer.layer()->parent()->clipper().getOrCalculateClipRects(context, parentClipRects); 33109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 332197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch ClipRect result = backgroundClipRectForPosition(parentClipRects, m_renderer.style()->position()); 33309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 33409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. 335197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (parentClipRects.fixed() && context.rootLayer->renderer() == m_renderer.view() && result != PaintInfo::infiniteRect()) 336197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch result.move(m_renderer.view()->frameView()->scrollOffsetForFixedPosition()); 33709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 338197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return result; 33909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 34009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 341197021e6b966cfb06891637935ef33fff06433d1Ben Murdochvoid RenderLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const 34207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{ 343197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (context.usesCache()) 344197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch clipRects = *getClipRects(context); 345197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch else 346197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch calculateClipRects(context, clipRects); 34709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 34809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 34909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)RenderLayer* RenderLayerClipper::clippingRootForPainting() const 35009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){ 351f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu const RenderLayer* current = m_renderer.layer(); 352197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // FIXME: getting rid of current->hasCompositedLayerMapping() here breaks the 353197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // compositing/backing/no-backing-for-clip.html layout test, because there is a 354197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // "composited but paints into ancestor" layer involved. However, it doesn't make sense that 355197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch // that check would be appropriate here but not inside the while loop below. 356197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (current->isPaintInvalidationContainer() || current->hasCompositedLayerMapping()) 357197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch return const_cast<RenderLayer*>(current); 358197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch 35909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) while (current) { 36009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (current->isRootLayer()) 36109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return const_cast<RenderLayer*>(current); 36209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 36309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) current = current->compositingContainer(); 36409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT(current); 365197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch if (current->transform() || current->isPaintInvalidationContainer()) 36609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return const_cast<RenderLayer*>(current); 36709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) } 36809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 36909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) ASSERT_NOT_REACHED(); 37009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return 0; 37109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} 37209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) 373c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink 374