Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
| 5 * | 5 * |
| 6 * Other contributors: | 6 * Other contributors: |
| 7 * Robert O'Callahan <roc+@cs.cmu.edu> | 7 * Robert O'Callahan <roc+@cs.cmu.edu> |
| 8 * David Baron <dbaron@fas.harvard.edu> | 8 * David Baron <dbaron@fas.harvard.edu> |
| 9 * Christian Biesinger <cbiesinger@web.de> | 9 * Christian Biesinger <cbiesinger@web.de> |
| 10 * Randall Jesup <rjesup@wgate.com> | 10 * Randall Jesup <rjesup@wgate.com> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 43 | 43 |
| 44 #include "core/paint/PaintLayerClipper.h" | 44 #include "core/paint/PaintLayerClipper.h" |
| 45 | 45 |
| 46 #include "core/frame/FrameView.h" | 46 #include "core/frame/FrameView.h" |
| 47 #include "core/frame/Settings.h" | 47 #include "core/frame/Settings.h" |
| 48 #include "core/layout/LayoutView.h" | 48 #include "core/layout/LayoutView.h" |
| 49 #include "core/paint/PaintLayer.h" | 49 #include "core/paint/PaintLayer.h" |
| 50 | 50 |
| 51 namespace blink { | 51 namespace blink { |
| 52 | 52 |
| 53 static void adjustClipRectsForChildren(const LayoutObject& layoutObject, ClipRec ts& clipRects) | 53 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, ClipRects& clipRects) |
| 54 { | 54 { |
| 55 EPosition position = layoutObject.style()->position(); | 55 EPosition position = layoutObject.styleRef().position(); |
| 56 // A fixed object is essentially the root of its containing block hierarchy, so when | 56 // A fixed object is essentially the root of its containing block hierarchy, so when |
| 57 // we encounter such an object, we reset our clip rects to the fixedClipRect . | 57 // we encounter such an object, we reset our clip rects to the fixedClipRect . |
| 58 if (position == FixedPosition) { | 58 if (position == FixedPosition) { |
| 59 clipRects.setPosClipRect(clipRects.fixedClipRect()); | 59 clipRects.setPosClipRect(clipRects.fixedClipRect()); |
| 60 clipRects.setOverflowClipRect(clipRects.fixedClipRect()); | 60 clipRects.setOverflowClipRect(clipRects.fixedClipRect()); |
| 61 clipRects.setFixed(true); | 61 clipRects.setFixed(true); |
| 62 } else if (position == RelativePosition) { | 62 } else if (position == RelativePosition) { |
| 63 clipRects.setPosClipRect(clipRects.overflowClipRect()); | 63 clipRects.setPosClipRect(clipRects.overflowClipRect()); |
| 64 } else if (position == AbsolutePosition) { | 64 } else if (position == AbsolutePosition) { |
| 65 clipRects.setOverflowClipRect(clipRects.posClipRect()); | 65 clipRects.setOverflowClipRect(clipRects.posClipRect()); |
| 66 } | 66 } |
| 67 } | 67 } |
| 68 | 68 |
| 69 static void applyClipRects(const ClipRectsContext& context, const LayoutObject& layoutObject, LayoutPoint offset, ClipRects& clipRects) | 69 static void applyClipRects(const ClipRectsContext& context, const LayoutBoxModel Object& layoutObject, LayoutPoint offset, ClipRects& clipRects) |
| 70 { | 70 { |
| 71 ASSERT(layoutObject.hasOverflowClip() || layoutObject.hasClip() || layoutObj ect.style()->containsPaint()); | 71 ASSERT(layoutObject.hasClipRelatedProperty()); |
| 72 LayoutView* view = layoutObject.view(); | 72 LayoutView* view = layoutObject.view(); |
| 73 ASSERT(view); | 73 ASSERT(view); |
| 74 if (clipRects.fixed() && context.rootLayer->layoutObject() == view) | 74 if (clipRects.fixed() && context.rootLayer->layoutObject() == view) |
| 75 offset -= toIntSize(view->frameView()->scrollPosition()); | 75 offset -= toIntSize(view->frameView()->scrollPosition()); |
| 76 if (layoutObject.hasOverflowClip() || (layoutObject.style()->containsPaint() && layoutObject.isBox())) { | 76 if (layoutObject.hasOverflowClip() || (layoutObject.styleRef().containsPaint () && layoutObject.isBox())) { |
| 77 ClipRect newOverflowClip = toLayoutBox(layoutObject).overflowClipRect(of fset, context.scrollbarRelevancy); | 77 ClipRect newOverflowClip = toLayoutBox(layoutObject).overflowClipRect(of fset, context.scrollbarRelevancy); |
| 78 newOverflowClip.setHasRadius(layoutObject.style()->hasBorderRadius()); | 78 newOverflowClip.setHasRadius(layoutObject.styleRef().hasBorderRadius()); |
| 79 clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.ov erflowClipRect())); | 79 clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.ov erflowClipRect())); |
| 80 if (layoutObject.isPositioned()) | 80 if (layoutObject.isPositioned()) |
| 81 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.pos ClipRect())); | 81 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.pos ClipRect())); |
| 82 if (layoutObject.isLayoutView()) | 82 if (layoutObject.isLayoutView()) |
| 83 clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.f ixedClipRect())); | 83 clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.f ixedClipRect())); |
| 84 if (layoutObject.style()->containsPaint()) { | 84 if (layoutObject.styleRef().containsPaint()) { |
| 85 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.pos ClipRect())); | 85 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.pos ClipRect())); |
| 86 clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.f ixedClipRect())); | 86 clipRects.setFixedClipRect(intersection(newOverflowClip, clipRects.f ixedClipRect())); |
| 87 } | 87 } |
| 88 } | 88 } |
| 89 if (layoutObject.hasClip()) { | 89 if (layoutObject.hasClip()) { |
| 90 LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset); | 90 LayoutRect newClip = toLayoutBox(layoutObject).clipRect(offset); |
| 91 clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect()). setIsClippedByClipCss()); | 91 clipRects.setPosClipRect(intersection(newClip, clipRects.posClipRect()). setIsClippedByClipCss()); |
| 92 clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowCl ipRect()).setIsClippedByClipCss()); | 92 clipRects.setOverflowClipRect(intersection(newClip, clipRects.overflowCl ipRect()).setIsClippedByClipCss()); |
| 93 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect ()).setIsClippedByClipCss()); | 93 clipRects.setFixedClipRect(intersection(newClip, clipRects.fixedClipRect ()).setIsClippedByClipCss()); |
| 94 | |
| 95 } | 94 } |
| 96 } | 95 } |
| 97 | 96 |
| 98 PaintLayerClipper::PaintLayerClipper(const LayoutBoxModelObject& layoutObject) | 97 PaintLayerClipper::PaintLayerClipper(const PaintLayer& layer) |
|
chrishtr
2016/01/27 21:00:34
Inline this just in case?
Xianzhu
2016/01/27 21:54:27
Done.
| |
| 99 : m_layoutObject(layoutObject) | 98 : m_layer(layer) |
| 100 { | 99 { |
| 101 } | 100 } |
| 102 | 101 |
| 103 ClipRects* PaintLayerClipper::clipRectsIfCached(const ClipRectsContext& context) const | 102 ClipRects* PaintLayerClipper::clipRectsIfCached(const ClipRectsContext& context) const |
| 104 { | 103 { |
| 105 ASSERT(context.usesCache()); | 104 ASSERT(context.usesCache()); |
| 106 if (!m_cache) | 105 if (!m_layer.clipRectsCache()) |
| 107 return 0; | 106 return nullptr; |
| 108 ClipRectsCache::Entry& entry = m_cache->get(context.cacheSlot()); | 107 ClipRectsCache::Entry& entry = m_layer.clipRectsCache()->get(context.cacheSl ot()); |
| 109 // FIXME: We used to ASSERT that we always got a consistent root layer. | 108 // FIXME: We used to ASSERT that we always got a consistent root layer. |
| 110 // We should add a test that has an inconsistent root. See | 109 // We should add a test that has an inconsistent root. See |
| 111 // http://crbug.com/366118 for an example. | 110 // http://crbug.com/366118 for an example. |
| 112 if (context.rootLayer != entry.root) | 111 if (context.rootLayer != entry.root) |
| 113 return 0; | 112 return 0; |
| 114 ASSERT(entry.scrollbarRelevancy == context.scrollbarRelevancy); | 113 ASSERT(entry.scrollbarRelevancy == context.scrollbarRelevancy); |
| 115 #ifdef CHECK_CACHED_CLIP_RECTS | 114 #ifdef CHECK_CACHED_CLIP_RECTS |
| 116 // This code is useful to check cached clip rects, but is too expensive to l eave enabled in debug builds by default. | 115 // This code is useful to check cached clip rects, but is too expensive to l eave enabled in debug builds by default. |
| 117 ClipRectsContext tempContext(context); | 116 ClipRectsContext tempContext(context); |
| 118 tempContext.cacheSlot = UncachedClipRects; | 117 tempContext.cacheSlot = UncachedClipRects; |
| 119 RefPtr<ClipRects> clipRects = ClipRects::create(); | 118 RefPtr<ClipRects> clipRects = ClipRects::create(); |
| 120 calculateClipRects(tempContext, *clipRects); | 119 calculateClipRects(tempContext, *clipRects); |
| 121 ASSERT(clipRects == *entry.clipRects); | 120 ASSERT(clipRects == *entry.clipRects); |
| 122 #endif | 121 #endif |
| 123 return entry.clipRects.get(); | 122 return entry.clipRects.get(); |
| 124 } | 123 } |
| 125 ClipRects* PaintLayerClipper::storeClipRectsInCache(const ClipRectsContext& cont ext, ClipRects* parentClipRects, const ClipRects& clipRects) const | 124 |
| 125 ClipRects& PaintLayerClipper::storeClipRectsInCache(const ClipRectsContext& cont ext, ClipRects* parentClipRects, const ClipRects& clipRects) const | |
| 126 { | 126 { |
| 127 ClipRectsCache::Entry& entry = cache().get(context.cacheSlot()); | 127 ClipRectsCache::Entry& entry = m_layer.ensureClipRectsCache().get(context.ca cheSlot()); |
| 128 entry.root = context.rootLayer; | 128 entry.root = context.rootLayer; |
| 129 #if ENABLE(ASSERT) | 129 #if ENABLE(ASSERT) |
| 130 entry.scrollbarRelevancy = context.scrollbarRelevancy; | 130 entry.scrollbarRelevancy = context.scrollbarRelevancy; |
| 131 #endif | 131 #endif |
| 132 if (parentClipRects) { | 132 if (parentClipRects) { |
| 133 // If our clip rects match the clip rects of our parent, we share storag e. | 133 // If our clip rects match the clip rects of our parent, we share storag e. |
| 134 if (clipRects == *parentClipRects) { | 134 if (clipRects == *parentClipRects) { |
| 135 entry.clipRects = parentClipRects; | 135 entry.clipRects = parentClipRects; |
| 136 return parentClipRects; | 136 return *parentClipRects; |
| 137 } | 137 } |
| 138 } | 138 } |
| 139 entry.clipRects = ClipRects::create(clipRects); | 139 entry.clipRects = ClipRects::create(clipRects); |
| 140 return entry.clipRects.get(); | 140 return *entry.clipRects; |
| 141 } | 141 } |
| 142 ClipRects* PaintLayerClipper::getClipRects(const ClipRectsContext& context) cons t | 142 |
| 143 ClipRects& PaintLayerClipper::getClipRects(const ClipRectsContext& context) cons t | |
| 143 { | 144 { |
| 144 if (ClipRects* result = clipRectsIfCached(context)) | 145 if (ClipRects* result = clipRectsIfCached(context)) |
| 145 return result; | 146 return *result; |
| 146 // Note that it's important that we call getClipRects on our parent | 147 // Note that it's important that we call getClipRects on our parent |
| 147 // before we call calculateClipRects so that calculateClipRects will hit | 148 // before we call calculateClipRects so that calculateClipRects will hit |
| 148 // the cache. | 149 // the cache. |
| 149 ClipRects* parentClipRects = 0; | 150 ClipRects* parentClipRects = nullptr; |
| 150 if (context.rootLayer != m_layoutObject.layer() && m_layoutObject.layer()->p arent()) | 151 if (context.rootLayer != &m_layer && m_layer.parent()) |
| 151 parentClipRects = m_layoutObject.layer()->parent()->clipper().getClipRec ts(context); | 152 parentClipRects = &m_layer.parent()->clipper().getClipRects(context); |
| 152 RefPtr<ClipRects> clipRects = ClipRects::create(); | 153 RefPtr<ClipRects> clipRects = ClipRects::create(); |
| 153 calculateClipRects(context, *clipRects); | 154 calculateClipRects(context, *clipRects); |
| 154 return storeClipRectsInCache(context, parentClipRects, *clipRects); | 155 return storeClipRectsInCache(context, parentClipRects, *clipRects); |
| 155 } | 156 } |
| 156 | 157 |
| 157 void PaintLayerClipper::clearClipRectsIncludingDescendants() | 158 void PaintLayerClipper::clearClipRectsIncludingDescendants() |
| 158 { | 159 { |
| 159 m_cache = nullptr; | 160 m_layer.clearClipRectsCache(); |
| 160 | 161 |
| 161 for (PaintLayer* layer = m_layoutObject.layer()->firstChild(); layer; layer = layer->nextSibling()) { | 162 for (PaintLayer* layer = m_layer.firstChild(); layer; layer = layer->nextSib ling()) { |
| 162 layer->clipper().clearClipRectsIncludingDescendants(); | 163 layer->clipper().clearClipRectsIncludingDescendants(); |
| 163 } | 164 } |
| 164 } | 165 } |
| 165 | 166 |
| 166 void PaintLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCacheSlot ca cheSlot) | 167 void PaintLayerClipper::clearClipRectsIncludingDescendants(ClipRectsCacheSlot ca cheSlot) |
| 167 { | 168 { |
| 168 if (m_cache) | 169 if (ClipRectsCache* cache = m_layer.clipRectsCache()) |
| 169 m_cache->clear(cacheSlot); | 170 cache->clear(cacheSlot); |
| 170 | 171 |
| 171 for (PaintLayer* layer = m_layoutObject.layer()->firstChild(); layer; layer = layer->nextSibling()) { | 172 for (PaintLayer* layer = m_layer.firstChild(); layer; layer = layer->nextSib ling()) { |
| 172 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); | 173 layer->clipper().clearClipRectsIncludingDescendants(cacheSlot); |
| 173 } | 174 } |
| 174 } | 175 } |
| 175 | 176 |
| 176 | |
| 177 LayoutRect PaintLayerClipper::localClipRect(const PaintLayer* clippingRootLayer) const | 177 LayoutRect PaintLayerClipper::localClipRect(const PaintLayer* clippingRootLayer) const |
| 178 { | 178 { |
| 179 LayoutRect layerBounds; | 179 LayoutRect layerBounds; |
| 180 ClipRect backgroundRect, foregroundRect; | 180 ClipRect backgroundRect, foregroundRect; |
| 181 ClipRectsContext context(clippingRootLayer, PaintingClipRects); | 181 ClipRectsContext context(clippingRootLayer, PaintingClipRects); |
| 182 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), layerBoun ds, backgroundRect, foregroundRect); | 182 calculateRects(context, LayoutRect(LayoutRect::infiniteIntRect()), layerBoun ds, backgroundRect, foregroundRect); |
| 183 | 183 |
| 184 LayoutRect clipRect = backgroundRect.rect(); | 184 LayoutRect clipRect = backgroundRect.rect(); |
| 185 // TODO(chrishtr): avoid converting to IntRect and back. | 185 // TODO(chrishtr): avoid converting to IntRect and back. |
| 186 if (clipRect == LayoutRect(LayoutRect::infiniteIntRect())) | 186 if (clipRect == LayoutRect(LayoutRect::infiniteIntRect())) |
| 187 return clipRect; | 187 return clipRect; |
| 188 | 188 |
| 189 LayoutPoint clippingRootOffset; | 189 LayoutPoint clippingRootOffset; |
| 190 m_layoutObject.layer()->convertToLayerCoords(clippingRootLayer, clippingRoot Offset); | 190 m_layer.convertToLayerCoords(clippingRootLayer, clippingRootOffset); |
| 191 clipRect.moveBy(-clippingRootOffset); | 191 clipRect.moveBy(-clippingRootOffset); |
| 192 | 192 |
| 193 return clipRect; | 193 return clipRect; |
| 194 } | 194 } |
| 195 | 195 |
| 196 void PaintLayerClipper::calculateRects(const ClipRectsContext& context, const La youtRect& paintDirtyRect, LayoutRect& layerBounds, | 196 void PaintLayerClipper::calculateRects(const ClipRectsContext& context, const La youtRect& paintDirtyRect, LayoutRect& layerBounds, |
| 197 ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutPoint* offse tFromRoot) const | 197 ClipRect& backgroundRect, ClipRect& foregroundRect, const LayoutPoint* offse tFromRoot) const |
| 198 { | 198 { |
| 199 bool isClippingRoot = m_layoutObject.layer() == context.rootLayer; | 199 bool isClippingRoot = &m_layer == context.rootLayer; |
| 200 LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); | |
| 200 | 201 |
| 201 if (!isClippingRoot && m_layoutObject.layer()->parent()) { | 202 if (!isClippingRoot && m_layer.parent()) { |
| 202 backgroundRect = backgroundClipRect(context); | 203 backgroundRect = backgroundClipRect(context); |
| 203 backgroundRect.move(context.subPixelAccumulation); | 204 backgroundRect.move(context.subPixelAccumulation); |
| 204 backgroundRect.intersect(paintDirtyRect); | 205 backgroundRect.intersect(paintDirtyRect); |
| 205 } else { | 206 } else { |
| 206 backgroundRect = paintDirtyRect; | 207 backgroundRect = paintDirtyRect; |
| 207 } | 208 } |
| 208 | 209 |
| 209 foregroundRect = backgroundRect; | 210 foregroundRect = backgroundRect; |
| 210 | 211 |
| 211 LayoutPoint offset; | 212 LayoutPoint offset; |
| 212 if (offsetFromRoot) | 213 if (offsetFromRoot) |
| 213 offset = *offsetFromRoot; | 214 offset = *offsetFromRoot; |
| 214 else | 215 else |
| 215 m_layoutObject.layer()->convertToLayerCoords(context.rootLayer, offset); | 216 m_layer.convertToLayerCoords(context.rootLayer, offset); |
| 216 layerBounds = LayoutRect(offset, LayoutSize(m_layoutObject.layer()->size())) ; | 217 layerBounds = LayoutRect(offset, LayoutSize(m_layer.size())); |
| 217 | 218 |
| 218 // Update the clip rects that will be passed to child layers. | 219 // Update the clip rects that will be passed to child layers. |
| 219 if ((m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) | 220 if ((layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) |
| 220 || (m_layoutObject.style()->containsPaint() && m_layoutObject.isBox())) { | 221 || (layoutObject.styleRef().containsPaint() && layoutObject.isBox())) { |
|
chrishtr
2016/01/27 21:00:34
How do you know styleRef() is now safe?
Xianzhu
2016/01/27 21:54:27
"m_layoutObject.style()->" is equivalent to "m_lay
| |
| 221 foregroundRect.intersect(toLayoutBox(m_layoutObject).overflowClipRect(of fset, context.scrollbarRelevancy)); | 222 foregroundRect.intersect(toLayoutBox(layoutObject).overflowClipRect(offs et, context.scrollbarRelevancy)); |
| 222 if (m_layoutObject.style()->hasBorderRadius()) | 223 if (layoutObject.styleRef().hasBorderRadius()) |
| 223 foregroundRect.setHasRadius(true); | 224 foregroundRect.setHasRadius(true); |
| 224 | 225 |
| 225 // FIXME: Does not do the right thing with columns yet, since we don't y et factor in the | 226 // FIXME: Does not do the right thing with columns yet, since we don't y et factor in the |
| 226 // individual column boxes as overflow. | 227 // individual column boxes as overflow. |
| 227 | 228 |
| 228 // The LayoutView is special since its overflow clipping rect may be lar ger than its box rect (crbug.com/492871). | 229 // The LayoutView is special since its overflow clipping rect may be lar ger than its box rect (crbug.com/492871). |
| 229 LayoutRect layerBoundsWithVisualOverflow = m_layoutObject.isLayoutView() ? toLayoutView(m_layoutObject).viewRect() : toLayoutBox(m_layoutObject).visualO verflowRect(); | 230 LayoutRect layerBoundsWithVisualOverflow = layoutObject.isLayoutView() ? toLayoutView(layoutObject).viewRect() : toLayoutBox(layoutObject).visualOverflo wRect(); |
| 230 toLayoutBox(m_layoutObject).flipForWritingMode(layerBoundsWithVisualOver flow); // PaintLayer are in physical coordinates, so the overflow has to be flip ped. | 231 toLayoutBox(layoutObject).flipForWritingMode(layerBoundsWithVisualOverfl ow); // PaintLayer are in physical coordinates, so the overflow has to be flippe d. |
| 231 layerBoundsWithVisualOverflow.moveBy(offset); | 232 layerBoundsWithVisualOverflow.moveBy(offset); |
| 232 backgroundRect.intersect(layerBoundsWithVisualOverflow); | 233 backgroundRect.intersect(layerBoundsWithVisualOverflow); |
| 233 } | 234 } |
| 234 | 235 |
| 235 // CSS clip (different than clipping due to overflow) can clip to any box, e ven if it falls outside of the border box. | 236 // CSS clip (different than clipping due to overflow) can clip to any box, e ven if it falls outside of the border box. |
| 236 if (m_layoutObject.hasClip()) { | 237 if (layoutObject.hasClip()) { |
| 237 // Clip applies to *us* as well, so go ahead and update the damageRect. | 238 // Clip applies to *us* as well, so go ahead and update the damageRect. |
| 238 LayoutRect newPosClip = toLayoutBox(m_layoutObject).clipRect(offset); | 239 LayoutRect newPosClip = toLayoutBox(layoutObject).clipRect(offset); |
| 239 backgroundRect.intersect(newPosClip); | 240 backgroundRect.intersect(newPosClip); |
| 240 backgroundRect.setIsClippedByClipCss(); | 241 backgroundRect.setIsClippedByClipCss(); |
| 241 foregroundRect.intersect(newPosClip); | 242 foregroundRect.intersect(newPosClip); |
| 242 foregroundRect.setIsClippedByClipCss(); | 243 foregroundRect.setIsClippedByClipCss(); |
| 243 } | 244 } |
| 244 } | 245 } |
| 245 | 246 |
| 246 void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, Clip Rects& clipRects) const | 247 void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, Clip Rects& clipRects) const |
| 247 { | 248 { |
| 248 bool rootLayerScrolls = m_layoutObject.document().settings() && m_layoutObje ct.document().settings()->rootLayerScrolls(); | 249 const LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); |
| 249 if (!m_layoutObject.layer()->parent() && !rootLayerScrolls) { | 250 bool rootLayerScrolls = layoutObject.document().settings() && layoutObject.d ocument().settings()->rootLayerScrolls(); |
| 251 if (!m_layer.parent() && !rootLayerScrolls) { | |
| 250 // The root layer's clip rect is always infinite. | 252 // The root layer's clip rect is always infinite. |
| 251 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); | 253 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 252 return; | 254 return; |
| 253 } | 255 } |
| 254 | 256 |
| 255 bool isClippingRoot = m_layoutObject.layer() == context.rootLayer; | 257 bool isClippingRoot = &m_layer == context.rootLayer; |
| 256 | 258 |
| 257 // For transformed layers, the root layer was shifted to be us, so there is no need to | 259 // For transformed layers, the root layer was shifted to be us, so there is no need to |
| 258 // examine the parent. We want to cache clip rects with us as the root. | 260 // examine the parent. We want to cache clip rects with us as the root. |
| 259 PaintLayer* parentLayer = !isClippingRoot ? m_layoutObject.layer()->parent() : 0; | 261 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; |
| 260 // Ensure that our parent's clip has been calculated so that we can examine the values. | 262 // Ensure that our parent's clip has been calculated so that we can examine the values. |
| 261 if (parentLayer) { | 263 if (parentLayer) { |
| 262 // FIXME: Why don't we just call getClipRects here? | 264 parentLayer->clipper().getOrCalculateClipRects(context, clipRects); |
| 263 if (context.usesCache() && parentLayer->clipper().cachedClipRects(contex t)) { | |
| 264 clipRects = *parentLayer->clipper().cachedClipRects(context); | |
| 265 } else { | |
| 266 parentLayer->clipper().calculateClipRects(context, clipRects); | |
| 267 } | |
| 268 } else { | 265 } else { |
| 269 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); | 266 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 270 } | 267 } |
| 271 | 268 |
| 272 adjustClipRectsForChildren(m_layoutObject, clipRects); | 269 adjustClipRectsForChildren(layoutObject, clipRects); |
| 273 | 270 |
| 274 if ((m_layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || m_layoutObject.hasClip() || m_layoutObject.style()->containsPaint()) { | 271 if ((layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) | | layoutObject.hasClip() || layoutObject.styleRef().containsPaint()) { |
| 275 // This offset cannot use convertToLayerCoords, because sometimes our ro otLayer may be across | 272 // This offset cannot use convertToLayerCoords, because sometimes our ro otLayer may be across |
| 276 // some transformed layer boundary, for example, in the PaintLayerCompos itor overlapMap, where | 273 // some transformed layer boundary, for example, in the PaintLayerCompos itor overlapMap, where |
| 277 // clipRects are needed in view space. | 274 // clipRects are needed in view space. |
| 278 applyClipRects(context, m_layoutObject, roundedLayoutPoint(m_layoutObjec t.localToAncestorPoint(FloatPoint(), context.rootLayer->layoutObject())), clipRe cts); | 275 applyClipRects(context, layoutObject, roundedLayoutPoint(layoutObject.lo calToAncestorPoint(FloatPoint(), context.rootLayer->layoutObject())), clipRects) ; |
| 279 } | 276 } |
| 280 } | 277 } |
| 281 | 278 |
| 282 static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPos ition position) | 279 static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPos ition position) |
| 283 { | 280 { |
| 284 if (position == FixedPosition) | 281 if (position == FixedPosition) |
| 285 return parentRects.fixedClipRect(); | 282 return parentRects.fixedClipRect(); |
| 286 | 283 |
| 287 if (position == AbsolutePosition) | 284 if (position == AbsolutePosition) |
| 288 return parentRects.posClipRect(); | 285 return parentRects.posClipRect(); |
| 289 | 286 |
| 290 return parentRects.overflowClipRect(); | 287 return parentRects.overflowClipRect(); |
| 291 } | 288 } |
| 292 | 289 |
| 293 ClipRect PaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const | 290 ClipRect PaintLayerClipper::backgroundClipRect(const ClipRectsContext& context) const |
| 294 { | 291 { |
| 295 ASSERT(m_layoutObject.layer()->parent()); | 292 ASSERT(m_layer.parent()); |
| 296 ASSERT(m_layoutObject.view()); | 293 LayoutView* layoutView = m_layer.layoutObject()->view(); |
| 294 ASSERT(layoutView); | |
| 297 | 295 |
| 298 RefPtr<ClipRects> parentClipRects = ClipRects::create(); | 296 RefPtr<ClipRects> parentClipRects = ClipRects::create(); |
| 299 if (m_layoutObject.layer() == context.rootLayer) | 297 if (&m_layer == context.rootLayer) |
| 300 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); | 298 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); |
| 301 else | 299 else |
| 302 m_layoutObject.layer()->parent()->clipper().getOrCalculateClipRects(cont ext, *parentClipRects); | 300 m_layer.parent()->clipper().getOrCalculateClipRects(context, *parentClip Rects); |
| 303 | 301 |
| 304 ClipRect result = backgroundClipRectForPosition(*parentClipRects, m_layoutOb ject.style()->position()); | 302 ClipRect result = backgroundClipRectForPosition(*parentClipRects, m_layer.la youtObject()->styleRef().position()); |
| 305 | 303 |
| 306 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. | 304 // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite. |
| 307 if (parentClipRects->fixed() && context.rootLayer->layoutObject() == m_layou tObject.view() && result != LayoutRect(LayoutRect::infiniteIntRect())) | 305 if (parentClipRects->fixed() && context.rootLayer->layoutObject() == layoutV iew && result != LayoutRect(LayoutRect::infiniteIntRect())) |
| 308 result.move(toIntSize(m_layoutObject.view()->frameView()->scrollPosition ())); | 306 result.move(toIntSize(layoutView->frameView()->scrollPosition())); |
| 309 | 307 |
| 310 return result; | 308 return result; |
| 311 } | 309 } |
| 312 | 310 |
| 313 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const | 311 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, ClipRects& clipRects) const |
| 314 { | 312 { |
| 315 if (context.usesCache()) | 313 if (context.usesCache()) |
| 316 clipRects = *getClipRects(context); | 314 clipRects = getClipRects(context); |
| 317 else | 315 else |
| 318 calculateClipRects(context, clipRects); | 316 calculateClipRects(context, clipRects); |
| 319 } | 317 } |
| 320 | 318 |
| 321 bool PaintLayerClipper::shouldRespectOverflowClip(const ClipRectsContext& contex t) const | 319 bool PaintLayerClipper::shouldRespectOverflowClip(const ClipRectsContext& contex t) const |
| 322 { | 320 { |
| 323 PaintLayer* layer = m_layoutObject.layer(); | 321 if (&m_layer != context.rootLayer) |
| 324 if (layer != context.rootLayer) | |
| 325 return true; | 322 return true; |
| 326 | 323 |
| 327 if (context.respectOverflowClip == IgnoreOverflowClip) | 324 if (context.respectOverflowClip == IgnoreOverflowClip) |
| 328 return false; | 325 return false; |
| 329 | 326 |
| 330 if (layer->isRootLayer() && context.respectOverflowClipForViewport == Ignore OverflowClip) | 327 if (m_layer.isRootLayer() && context.respectOverflowClipForViewport == Ignor eOverflowClip) |
| 331 return false; | 328 return false; |
| 332 | 329 |
| 333 return true; | 330 return true; |
| 334 } | 331 } |
| 335 | 332 |
| 336 ClipRects* PaintLayerClipper::paintingClipRects(const PaintLayer* rootLayer, Sho uldRespectOverflowClip respectOverflowClip, const LayoutSize& subpixelAccumulati on) const | 333 ClipRects& PaintLayerClipper::paintingClipRects(const PaintLayer* rootLayer, Sho uldRespectOverflowClip respectOverflowClip, const LayoutSize& subpixelAccumulati on) const |
| 337 { | 334 { |
| 338 ClipRectsContext context(rootLayer, PaintingClipRects, IgnoreOverlayScrollba rSize, subpixelAccumulation); | 335 ClipRectsContext context(rootLayer, PaintingClipRects, IgnoreOverlayScrollba rSize, subpixelAccumulation); |
| 339 if (respectOverflowClip == IgnoreOverflowClip) | 336 if (respectOverflowClip == IgnoreOverflowClip) |
| 340 context.setIgnoreOverflowClip(); | 337 context.setIgnoreOverflowClip(); |
| 341 return getClipRects(context); | 338 return getClipRects(context); |
| 342 } | 339 } |
| 343 | 340 |
| 344 } // namespace blink | 341 } // namespace blink |
| OLD | NEW |