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 |
| 3 * reserved. |
3 * | 4 * |
4 * Portions are Copyright (C) 1998 Netscape Communications Corporation. | 5 * Portions are Copyright (C) 1998 Netscape Communications Corporation. |
5 * | 6 * |
6 * Other contributors: | 7 * Other contributors: |
7 * Robert O'Callahan <roc+@cs.cmu.edu> | 8 * Robert O'Callahan <roc+@cs.cmu.edu> |
8 * David Baron <dbaron@fas.harvard.edu> | 9 * David Baron <dbaron@fas.harvard.edu> |
9 * Christian Biesinger <cbiesinger@web.de> | 10 * Christian Biesinger <cbiesinger@web.de> |
10 * Randall Jesup <rjesup@wgate.com> | 11 * Randall Jesup <rjesup@wgate.com> |
11 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> | 12 * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de> |
12 * Josh Soref <timeless@mac.com> | 13 * Josh Soref <timeless@mac.com> |
13 * Boris Zbarsky <bzbarsky@mit.edu> | 14 * Boris Zbarsky <bzbarsky@mit.edu> |
14 * | 15 * |
15 * This library is free software; you can redistribute it and/or | 16 * This library is free software; you can redistribute it and/or |
16 * modify it under the terms of the GNU Lesser General Public | 17 * modify it under the terms of the GNU Lesser General Public |
17 * License as published by the Free Software Foundation; either | 18 * License as published by the Free Software Foundation; either |
18 * version 2.1 of the License, or (at your option) any later version. | 19 * version 2.1 of the License, or (at your option) any later version. |
19 * | 20 * |
20 * This library is distributed in the hope that it will be useful, | 21 * This library is distributed in the hope that it will be useful, |
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 22 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
23 * Lesser General Public License for more details. | 24 * Lesser General Public License for more details. |
24 * | 25 * |
25 * You should have received a copy of the GNU Lesser General Public | 26 * You should have received a copy of the GNU Lesser General Public |
26 * License along with this library; if not, write to the Free Software | 27 * License along with this library; if not, write to the Free Software |
27 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 US
A | 28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
28 * | 29 * |
29 * Alternatively, the contents of this file may be used under the terms | 30 * Alternatively, the contents of this file may be used under the terms |
30 * of either the Mozilla Public License Version 1.1, found at | 31 * of either the Mozilla Public License Version 1.1, found at |
31 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public | 32 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public |
32 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html | 33 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html |
33 * (the "GPL"), in which case the provisions of the MPL or the GPL are | 34 * (the "GPL"), in which case the provisions of the MPL or the GPL are |
34 * applicable instead of those above. If you wish to allow use of your | 35 * applicable instead of those above. If you wish to allow use of your |
35 * version of this file only under the terms of one of those two | 36 * version of this file only under the terms of one of those two |
36 * licenses (the MPL or the GPL) and not to allow others to use your | 37 * licenses (the MPL or the GPL) and not to allow others to use your |
37 * version of this file under the LGPL, indicate your decision by | 38 * version of this file under the LGPL, indicate your decision by |
38 * deletingthe provisions above and replace them with the notice and | 39 * deletingthe provisions above and replace them with the notice and |
39 * other provisions required by the MPL or the GPL, as the case may be. | 40 * other provisions required by the MPL or the GPL, as the case may be. |
40 * If you do not delete the provisions above, a recipient may use your | 41 * If you do not delete the provisions above, a recipient may use your |
41 * version of this file under any of the LGPL, the MPL or the GPL. | 42 * version of this file under any of the LGPL, the MPL or the GPL. |
42 */ | 43 */ |
43 | 44 |
44 #include "core/paint/PaintLayerClipper.h" | 45 #include "core/paint/PaintLayerClipper.h" |
45 | 46 |
46 #include "core/frame/FrameView.h" | 47 #include "core/frame/FrameView.h" |
47 #include "core/frame/Settings.h" | 48 #include "core/frame/Settings.h" |
48 #include "core/layout/LayoutView.h" | 49 #include "core/layout/LayoutView.h" |
49 #include "core/layout/svg/LayoutSVGRoot.h" | 50 #include "core/layout/svg/LayoutSVGRoot.h" |
50 #include "core/paint/PaintLayer.h" | 51 #include "core/paint/PaintLayer.h" |
51 | 52 |
52 namespace blink { | 53 namespace blink { |
53 | 54 |
54 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, | 55 static void adjustClipRectsForChildren(const LayoutBoxModelObject& layoutObject, |
55 ClipRects& clipRects) { | 56 ClipRects& clipRects) { |
56 EPosition position = layoutObject.styleRef().position(); | 57 EPosition position = layoutObject.styleRef().position(); |
57 // A fixed object is essentially the root of its containing block hierarchy, s
o when | 58 // A fixed object is essentially the root of its containing block hierarchy, |
58 // we encounter such an object, we reset our clip rects to the fixedClipRect. | 59 // so when we encounter such an object, we reset our clip rects to the |
| 60 // fixedClipRect. |
59 if (position == FixedPosition) { | 61 if (position == FixedPosition) { |
60 clipRects.setPosClipRect(clipRects.fixedClipRect()); | 62 clipRects.setPosClipRect(clipRects.fixedClipRect()); |
61 clipRects.setOverflowClipRect(clipRects.fixedClipRect()); | 63 clipRects.setOverflowClipRect(clipRects.fixedClipRect()); |
62 clipRects.setFixed(true); | 64 clipRects.setFixed(true); |
63 } else if (position == RelativePosition) { | 65 } else if (position == RelativePosition) { |
64 clipRects.setPosClipRect(clipRects.overflowClipRect()); | 66 clipRects.setPosClipRect(clipRects.overflowClipRect()); |
65 } else if (position == AbsolutePosition) { | 67 } else if (position == AbsolutePosition) { |
66 clipRects.setOverflowClipRect(clipRects.posClipRect()); | 68 clipRects.setOverflowClipRect(clipRects.posClipRect()); |
67 } | 69 } |
68 } | 70 } |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
238 // Update the clip rects that will be passed to child layers. | 240 // Update the clip rects that will be passed to child layers. |
239 if ((layoutObject.hasOverflowClip() || | 241 if ((layoutObject.hasOverflowClip() || |
240 layoutObject.styleRef().containsPaint()) && | 242 layoutObject.styleRef().containsPaint()) && |
241 shouldRespectOverflowClip(context)) { | 243 shouldRespectOverflowClip(context)) { |
242 foregroundRect.intersect( | 244 foregroundRect.intersect( |
243 toLayoutBox(layoutObject) | 245 toLayoutBox(layoutObject) |
244 .overflowClipRect(offset, context.overlayScrollbarClipBehavior)); | 246 .overflowClipRect(offset, context.overlayScrollbarClipBehavior)); |
245 if (layoutObject.styleRef().hasBorderRadius()) | 247 if (layoutObject.styleRef().hasBorderRadius()) |
246 foregroundRect.setHasRadius(true); | 248 foregroundRect.setHasRadius(true); |
247 | 249 |
248 // FIXME: Does not do the right thing with columns yet, since we don't yet f
actor in the | 250 // FIXME: Does not do the right thing with columns yet, since we don't yet |
249 // individual column boxes as overflow. | 251 // factor in the individual column boxes as overflow. |
250 | 252 |
251 // The LayoutView is special since its overflow clipping rect may be larger
than its box rect (crbug.com/492871). | 253 // The LayoutView is special since its overflow clipping rect may be larger |
| 254 // than its box rect (crbug.com/492871). |
252 LayoutRect layerBoundsWithVisualOverflow = | 255 LayoutRect layerBoundsWithVisualOverflow = |
253 layoutObject.isLayoutView() | 256 layoutObject.isLayoutView() |
254 ? toLayoutView(layoutObject).viewRect() | 257 ? toLayoutView(layoutObject).viewRect() |
255 : toLayoutBox(layoutObject).visualOverflowRect(); | 258 : toLayoutBox(layoutObject).visualOverflowRect(); |
256 toLayoutBox(layoutObject) | 259 // PaintLayer are in physical coordinates, so the overflow has to be |
257 .flipForWritingMode( | 260 // flipped. |
258 layerBoundsWithVisualOverflow); // PaintLayer are in physical coord
inates, so the overflow has to be flipped. | 261 toLayoutBox(layoutObject).flipForWritingMode(layerBoundsWithVisualOverflow); |
259 layerBoundsWithVisualOverflow.moveBy(offset); | 262 layerBoundsWithVisualOverflow.moveBy(offset); |
260 backgroundRect.intersect(layerBoundsWithVisualOverflow); | 263 backgroundRect.intersect(layerBoundsWithVisualOverflow); |
261 } | 264 } |
262 | 265 |
263 // CSS clip (different than clipping due to overflow) can clip to any box, eve
n if it falls outside of the border box. | 266 // CSS clip (different than clipping due to overflow) can clip to any box, |
| 267 // even if it falls outside of the border box. |
264 if (layoutObject.hasClip()) { | 268 if (layoutObject.hasClip()) { |
265 // Clip applies to *us* as well, so go ahead and update the damageRect. | 269 // Clip applies to *us* as well, so go ahead and update the damageRect. |
266 LayoutRect newPosClip = toLayoutBox(layoutObject).clipRect(offset); | 270 LayoutRect newPosClip = toLayoutBox(layoutObject).clipRect(offset); |
267 backgroundRect.intersect(newPosClip); | 271 backgroundRect.intersect(newPosClip); |
268 backgroundRect.setIsClippedByClipCss(); | 272 backgroundRect.setIsClippedByClipCss(); |
269 foregroundRect.intersect(newPosClip); | 273 foregroundRect.intersect(newPosClip); |
270 foregroundRect.setIsClippedByClipCss(); | 274 foregroundRect.setIsClippedByClipCss(); |
271 } | 275 } |
272 } | 276 } |
273 | 277 |
274 void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, | 278 void PaintLayerClipper::calculateClipRects(const ClipRectsContext& context, |
275 ClipRects& clipRects) const { | 279 ClipRects& clipRects) const { |
276 const LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); | 280 const LayoutBoxModelObject& layoutObject = *m_layer.layoutObject(); |
277 if (!m_layer.parent() && | 281 if (!m_layer.parent() && |
278 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { | 282 !RuntimeEnabledFeatures::rootLayerScrollingEnabled()) { |
279 // The root layer's clip rect is always infinite. | 283 // The root layer's clip rect is always infinite. |
280 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); | 284 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); |
281 return; | 285 return; |
282 } | 286 } |
283 | 287 |
284 bool isClippingRoot = &m_layer == context.rootLayer; | 288 bool isClippingRoot = &m_layer == context.rootLayer; |
285 | 289 |
286 // For transformed layers, the root layer was shifted to be us, so there is no
need to | 290 // For transformed layers, the root layer was shifted to be us, so there is no |
287 // examine the parent. We want to cache clip rects with us as the root. | 291 // need to examine the parent. We want to cache clip rects with us as the |
| 292 // root. |
288 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; | 293 PaintLayer* parentLayer = !isClippingRoot ? m_layer.parent() : nullptr; |
289 // Ensure that our parent's clip has been calculated so that we can examine th
e values. | 294 // Ensure that our parent's clip has been calculated so that we can examine |
| 295 // the values. |
290 if (parentLayer) { | 296 if (parentLayer) { |
291 parentLayer->clipper().getOrCalculateClipRects(context, clipRects); | 297 parentLayer->clipper().getOrCalculateClipRects(context, clipRects); |
292 } else { | 298 } else { |
293 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); | 299 clipRects.reset(LayoutRect(LayoutRect::infiniteIntRect())); |
294 } | 300 } |
295 | 301 |
296 adjustClipRectsForChildren(layoutObject, clipRects); | 302 adjustClipRectsForChildren(layoutObject, clipRects); |
297 | 303 |
298 if ((layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || | 304 if ((layoutObject.hasOverflowClip() && shouldRespectOverflowClip(context)) || |
299 (layoutObject.isSVGRoot() && | 305 (layoutObject.isSVGRoot() && |
300 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || | 306 toLayoutSVGRoot(&layoutObject)->shouldApplyViewportClip()) || |
301 layoutObject.hasClip() || layoutObject.styleRef().containsPaint()) { | 307 layoutObject.hasClip() || layoutObject.styleRef().containsPaint()) { |
302 // This offset cannot use convertToLayerCoords, because sometimes our rootLa
yer may be across | 308 // This offset cannot use convertToLayerCoords, because sometimes our |
303 // some transformed layer boundary, for example, in the PaintLayerCompositor
overlapMap, where | 309 // rootLayer may be across some transformed layer boundary, for example, in |
304 // clipRects are needed in view space. | 310 // the PaintLayerCompositor overlapMap, where clipRects are needed in view |
| 311 // space. |
305 applyClipRects(context, layoutObject, | 312 applyClipRects(context, layoutObject, |
306 roundedLayoutPoint(layoutObject.localToAncestorPoint( | 313 roundedLayoutPoint(layoutObject.localToAncestorPoint( |
307 FloatPoint(), context.rootLayer->layoutObject())), | 314 FloatPoint(), context.rootLayer->layoutObject())), |
308 clipRects); | 315 clipRects); |
309 } | 316 } |
310 } | 317 } |
311 | 318 |
312 static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, | 319 static ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, |
313 EPosition position) { | 320 EPosition position) { |
314 if (position == FixedPosition) | 321 if (position == FixedPosition) |
(...skipping 14 matching lines...) Expand all Loading... |
329 RefPtr<ClipRects> parentClipRects = ClipRects::create(); | 336 RefPtr<ClipRects> parentClipRects = ClipRects::create(); |
330 if (&m_layer == context.rootLayer) | 337 if (&m_layer == context.rootLayer) |
331 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); | 338 parentClipRects->reset(LayoutRect(LayoutRect::infiniteIntRect())); |
332 else | 339 else |
333 m_layer.parent()->clipper().getOrCalculateClipRects(context, | 340 m_layer.parent()->clipper().getOrCalculateClipRects(context, |
334 *parentClipRects); | 341 *parentClipRects); |
335 | 342 |
336 ClipRect result = backgroundClipRectForPosition( | 343 ClipRect result = backgroundClipRectForPosition( |
337 *parentClipRects, m_layer.layoutObject()->styleRef().position()); | 344 *parentClipRects, m_layer.layoutObject()->styleRef().position()); |
338 | 345 |
339 // Note: infinite clipRects should not be scrolled here, otherwise they will a
ccidentally no longer be considered infinite. | 346 // Note: infinite clipRects should not be scrolled here, otherwise they will |
| 347 // accidentally no longer be considered infinite. |
340 if (parentClipRects->fixed() && | 348 if (parentClipRects->fixed() && |
341 context.rootLayer->layoutObject() == layoutView && | 349 context.rootLayer->layoutObject() == layoutView && |
342 result != LayoutRect(LayoutRect::infiniteIntRect())) | 350 result != LayoutRect(LayoutRect::infiniteIntRect())) |
343 result.move(toIntSize(layoutView->frameView()->scrollPosition())); | 351 result.move(toIntSize(layoutView->frameView()->scrollPosition())); |
344 | 352 |
345 return result; | 353 return result; |
346 } | 354 } |
347 | 355 |
348 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, | 356 void PaintLayerClipper::getOrCalculateClipRects(const ClipRectsContext& context, |
349 ClipRects& clipRects) const { | 357 ClipRects& clipRects) const { |
(...skipping 23 matching lines...) Expand all Loading... |
373 ShouldRespectOverflowClipType respectOverflowClip, | 381 ShouldRespectOverflowClipType respectOverflowClip, |
374 const LayoutSize& subpixelAccumulation) const { | 382 const LayoutSize& subpixelAccumulation) const { |
375 ClipRectsContext context(rootLayer, PaintingClipRects, | 383 ClipRectsContext context(rootLayer, PaintingClipRects, |
376 IgnoreOverlayScrollbarSize, subpixelAccumulation); | 384 IgnoreOverlayScrollbarSize, subpixelAccumulation); |
377 if (respectOverflowClip == IgnoreOverflowClip) | 385 if (respectOverflowClip == IgnoreOverflowClip) |
378 context.setIgnoreOverflowClip(); | 386 context.setIgnoreOverflowClip(); |
379 return getClipRects(context); | 387 return getClipRects(context); |
380 } | 388 } |
381 | 389 |
382 } // namespace blink | 390 } // namespace blink |
OLD | NEW |