⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 120464 in webkit


Ignore:
Timestamp:
Jun 15, 2012, 8:37:12 AM (14 years ago)
Author:
schenney@chromium.org
Message:

SVG Composite of Offset filters incorrectly clips
https://bugs.webkit.org/show_bug.cgi?id=77660

Reviewed by Dirk Schulze.

Source/WebCore:

Prior to this patch, when a group of filtered objects was used as input to another filter,
the filter only operated on the stroke boundary of the group, and hence excluded the results
of filtering elements within the group, or extraneously included regions clipped from the
elements in the group.

This patch modifies the strokeBoundingBox of SVG container elements to
be the union of the repaint rects for the children. This modifes the
results returned for sizing filters and for absoluteRects, which will cause
inline layout around the group to factor in the resources applied to
the group's children.

The relevant spec entry is this, in Section 3.7 of the SVG 1.1 spec: "...the result must be
as though the paint operations had been applied to an intermediate canvas initialized to
transparent black, of a size determined by the rules given in Filter Effects then filtered
by the processes defined in Filter Effects." In this case the "paint operations" is implied
to include the result of applying "paint" but no resources to the group, which in turn would
have resources applied to the children of the group. This makes the most sense, as the current,
incorrect behavior makes it extremely diffucult to understand the actions of filters on
groups of filtered content.

Tests: svg/filters/container-with-filters-expected.svg

svg/filters/container-with-filters.svg

  • rendering/svg/RenderSVGContainer.cpp:

(WebCore::RenderSVGContainer::updateCachedBoundaries):

  • rendering/svg/RenderSVGRoot.cpp:

(WebCore::RenderSVGRoot::updateCachedBoundaries):

  • rendering/svg/SVGRenderSupport.cpp:

(WebCore::SVGRenderSupport::computeContainerBoundingBoxes):

LayoutTests:

  • svg/filters/container-with-filters-expected.svg: Added.
  • svg/filters/container-with-filters.svg: Added.
Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r120456 r120464  
     12012-06-15  Stephen Chenney  <schenney@chromium.org>
     2
     3        SVG Composite of Offset filters incorrectly clips
     4        https://bugs.webkit.org/show_bug.cgi?id=77660
     5
     6        Reviewed by Dirk Schulze.
     7
     8        * svg/filters/container-with-filters-expected.svg: Added.
     9        * svg/filters/container-with-filters.svg: Added.
     10
    1112012-06-15  Ilya Tikhonovsky  <loislo@chromium.org>
    212
  • trunk/Source/WebCore/ChangeLog

    r120462 r120464  
     12012-06-15  Stephen Chenney  <schenney@chromium.org>
     2
     3        SVG Composite of Offset filters incorrectly clips
     4        https://bugs.webkit.org/show_bug.cgi?id=77660
     5
     6        Reviewed by Dirk Schulze.
     7
     8        Prior to this patch, when a group of filtered objects was used as input to another filter,
     9        the filter only operated on the stroke boundary of the group, and hence excluded the results
     10        of filtering elements within the group, or extraneously included regions clipped from the
     11        elements in the group.
     12
     13        This patch modifies the strokeBoundingBox of SVG container elements to
     14        be the union of the repaint rects for the children. This modifes the
     15        results returned for sizing filters and for absoluteRects, which will cause
     16        inline layout around the group to factor in the resources applied to
     17        the group's children.
     18
     19        The relevant spec entry is this, in Section 3.7 of the SVG 1.1 spec: "...the result must be
     20        as though the paint operations had been applied to an intermediate canvas initialized to
     21        transparent black, of a size determined by the rules given in Filter Effects then filtered
     22        by the processes defined in Filter Effects." In this case the "paint operations" is implied
     23        to include the result of applying "paint" but no resources to the group, which in turn would
     24        have resources applied to the children of the group. This makes the most sense, as the current,
     25        incorrect behavior makes it extremely diffucult to understand the actions of filters on
     26        groups of filtered content.
     27
     28        Tests: svg/filters/container-with-filters-expected.svg
     29               svg/filters/container-with-filters.svg
     30
     31        * rendering/svg/RenderSVGContainer.cpp:
     32        (WebCore::RenderSVGContainer::updateCachedBoundaries):
     33        * rendering/svg/RenderSVGRoot.cpp:
     34        (WebCore::RenderSVGRoot::updateCachedBoundaries):
     35        * rendering/svg/SVGRenderSupport.cpp:
     36        (WebCore::SVGRenderSupport::computeContainerBoundingBoxes):
     37
    1382012-06-15  David Kilzer  <ddkilzer@apple.com>
    239
  • trunk/Source/WebCore/rendering/svg/RenderSVGContainer.cpp

    r118608 r120464  
    164164void RenderSVGContainer::updateCachedBoundaries()
    165165{
    166     m_objectBoundingBox = FloatRect();
    167     m_objectBoundingBoxValid = false;
    168     m_strokeBoundingBox = FloatRect();
    169     m_repaintBoundingBox = FloatRect();
    170 
    171166    SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox);
    172167    SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
  • trunk/Source/WebCore/rendering/svg/RenderSVGRoot.cpp

    r118608 r120464  
    405405void RenderSVGRoot::updateCachedBoundaries()
    406406{
    407     m_objectBoundingBox = FloatRect();
    408     m_objectBoundingBoxValid = false;
    409     m_strokeBoundingBox = FloatRect();
    410     m_repaintBoundingBox = FloatRect();
    411 
    412407    SVGRenderSupport::computeContainerBoundingBoxes(this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBox);
    413408    SVGRenderSupport::intersectRepaintRectWithResources(this, m_repaintBoundingBox);
  • trunk/Source/WebCore/rendering/svg/SVGRenderSupport.cpp

    r118567 r120464  
    122122void SVGRenderSupport::computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox)
    123123{
     124    objectBoundingBox = FloatRect();
     125    objectBoundingBoxValid = false;
     126    strokeBoundingBox = FloatRect();
     127
     128    // When computing the strokeBoundingBox, we use the repaintRects of the container's children so that the container's stroke includes
     129    // the resources applied to the children (such as clips and filters). This allows filters applied to containers to correctly bound
     130    // the children, and also improves inlining of SVG content, as the stroke bound is used in that situation also.
    124131    for (RenderObject* current = container->firstChild(); current; current = current->nextSibling()) {
    125132        if (current->isSVGHiddenContainer())
     
    129136        if (transform.isIdentity()) {
    130137            updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox());
    131             strokeBoundingBox.unite(current->strokeBoundingBox());
    132             repaintBoundingBox.unite(current->repaintRectInLocalCoordinates());
     138            strokeBoundingBox.unite(current->repaintRectInLocalCoordinates());
    133139        } else {
    134140            updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, transform.mapRect(current->objectBoundingBox()));
    135             strokeBoundingBox.unite(transform.mapRect(current->strokeBoundingBox()));
    136             repaintBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
     141            strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
    137142        }
    138143    }
     144
     145    repaintBoundingBox = strokeBoundingBox;
    139146}
    140147
Note: See TracChangeset for help on using the changeset viewer.