Changeset 164252 in webkit


Ignore:
Timestamp:
Feb 17, 2014 3:45:44 PM (10 years ago)
Author:
Simon Fraser
Message:

box-shadows get truncated with a combination of transforms and clip: (affects Google Maps)
https://bugs.webkit.org/show_bug.cgi?id=128937

Source/WebCore:

Reviewed by Dean Jackson.

RenderLayer::calculateLayerBounds() incorrectly assumed that if localClipRect() returns
a non-infinite rect, that rect is OK to use as the compositing bounds.

That is not a valid assumption when clip() has a larger rect than the element (e.g.
with negative top/left in the rect). In that case, localClipRect() still just
returns the background rect, but we actually need a larger compositing layer
to show the unclipped parts of descendants.

Fix by detecting clip() that exceeds the renderer bounds, and when it does,
not early returning in the UseLocalClipRectIfPossible clause.

Test: compositing/geometry/css-clip-oversize.html

  • rendering/RenderLayer.cpp:

(WebCore::RenderLayer::localClipRect): Do a convertToLayerCoords()
because we need offsetFromRoot later, and we can pass our value down to
calculateRects(). Compute clipExceedsBounds based on the CSS clip rect.
(WebCore::RenderLayer::calculateClipRects): Don't early return if clipExceedsBounds
is true.

  • rendering/RenderLayer.h:

LayoutTests:

Reviewed by Dean Jackson.

Test with CSS clip() with a rect larger than the border box, and compositing.

  • compositing/geometry/clip-expected.txt: New expectation. This is a progression.
  • compositing/geometry/css-clip-oversize-expected.html: Added.
  • compositing/geometry/css-clip-oversize.html: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r164249 r164252  
     12014-02-17  Simon Fraser  <simon.fraser@apple.com>
     2
     3        box-shadows get truncated with a combination of transforms and clip: (affects Google Maps)
     4        https://bugs.webkit.org/show_bug.cgi?id=128937
     5
     6        Reviewed by Dean Jackson.
     7       
     8        Test with CSS clip() with a rect larger than the border box, and compositing.
     9
     10        * compositing/geometry/clip-expected.txt: New expectation. This is a progression.
     11        * compositing/geometry/css-clip-oversize-expected.html: Added.
     12        * compositing/geometry/css-clip-oversize.html: Added.
     13
    1142014-02-17  Chris Fleizach  <cfleizach@apple.com>
    215
  • trunk/LayoutTests/compositing/geometry/clip-expected.txt

    r146531 r164252  
    99      (children 2
    1010        (GraphicsLayer
    11           (position 20.00 20.00)
    12           (bounds 100.00 100.00)
    13           (contentsOpaque 1)
     11          (position 15.00 15.00)
     12          (bounds 110.00 110.00)
    1413          (drawsContent 1)
    1514          (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 1.00 1.00])
  • trunk/Source/WebCore/ChangeLog

    r164251 r164252  
     12014-02-17  Simon Fraser  <simon.fraser@apple.com>
     2
     3        box-shadows get truncated with a combination of transforms and clip: (affects Google Maps)
     4        https://bugs.webkit.org/show_bug.cgi?id=128937
     5
     6        Reviewed by Dean Jackson.
     7       
     8        RenderLayer::calculateLayerBounds() incorrectly assumed that if localClipRect() returns
     9        a non-infinite rect, that rect is OK to use as the compositing bounds.
     10       
     11        That is not a valid assumption when clip() has a larger rect than the element (e.g.
     12        with negative top/left in the rect). In that case, localClipRect() still just
     13        returns the background rect, but we actually need a larger compositing layer
     14        to show the unclipped parts of descendants.
     15       
     16        Fix by detecting clip() that exceeds the renderer bounds, and when it does,
     17        not early returning in the UseLocalClipRectIfPossible clause.
     18
     19        Test: compositing/geometry/css-clip-oversize.html
     20
     21        * rendering/RenderLayer.cpp:
     22        (WebCore::RenderLayer::localClipRect): Do a convertToLayerCoords()
     23        because we need offsetFromRoot later, and we can pass our value down to
     24        calculateRects(). Compute clipExceedsBounds based on the CSS clip rect.
     25        (WebCore::RenderLayer::calculateClipRects): Don't early return if clipExceedsBounds
     26        is true.
     27        * rendering/RenderLayer.h:
     28
    1292014-02-17  Antti Koivisto  <antti@apple.com>
    230
  • trunk/Source/WebCore/rendering/RenderLayer.cpp

    r164103 r164252  
    55275527}
    55285528
    5529 LayoutRect RenderLayer::localClipRect() const
    5530 {
     5529LayoutRect RenderLayer::localClipRect(bool& clipExceedsBounds) const
     5530{
     5531    clipExceedsBounds = false;
     5532   
    55315533    // FIXME: border-radius not accounted for.
    55325534    // FIXME: Regions not accounted for.
    55335535    RenderLayer* clippingRootLayer = clippingRootForPainting();
     5536
     5537    LayoutPoint offsetFromRoot;
     5538    convertToLayerCoords(clippingRootLayer, offsetFromRoot);
     5539
    55345540    LayoutRect layerBounds;
    55355541    ClipRect backgroundRect, foregroundRect, outlineRect;
    55365542    ClipRectsContext clipRectsContext(clippingRootLayer, 0, PaintingClipRects);
    5537     calculateRects(clipRectsContext, LayoutRect::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
     5543    calculateRects(clipRectsContext, LayoutRect::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect, &offsetFromRoot);
    55385544
    55395545    LayoutRect clipRect = backgroundRect.rect();
    55405546    if (clipRect == LayoutRect::infiniteRect())
    55415547        return clipRect;
     5548
     5549    if (renderer().hasClip()) {
     5550        // CSS clip may be larger than our border box.
     5551        LayoutRect cssClipRect = toRenderBox(renderer()).clipRect(offsetFromRoot, clipRectsContext.region);
     5552        clipExceedsBounds = !clipRect.contains(cssClipRect);
     5553    }
    55425554
    55435555    LayoutPoint clippingRootOffset;
     
    57305742
    57315743    if (flags & UseLocalClipRectIfPossible) {
    5732         LayoutRect localClipRect = this->localClipRect();
    5733         if (localClipRect != LayoutRect::infiniteRect()) {
     5744        bool clipExceedsBounds = false;
     5745        LayoutRect localClipRect = this->localClipRect(clipExceedsBounds);
     5746        if (localClipRect != LayoutRect::infiniteRect() && !clipExceedsBounds) {
    57345747            if ((flags & IncludeSelfTransform) && paintsWithTransform(PaintBehaviorNormal))
    57355748                localClipRect = transform()->mapRect(localClipRect);
  • trunk/Source/WebCore/rendering/RenderLayer.h

    r163955 r164252  
    694694    LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
    695695    LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
    696     LayoutRect localClipRect() const; // Returns the background clip rect of the layer in the local coordinate space.
     696    LayoutRect localClipRect(bool& clipExceedsBounds) const; // Returns the background clip rect of the layer in the local coordinate space.
    697697
    698698    // Pass offsetFromRoot if known.
Note: See TracChangeset for help on using the changeset viewer.