Title: [105612] trunk
Revision
105612
Author
[email protected]
Date
2012-01-23 04:42:42 -0800 (Mon, 23 Jan 2012)

Log Message

<feImage> has problems referencing local elements
https://bugs.webkit.org/show_bug.cgi?id=76800

Reviewed by Zoltan Herczeg.

Source/WebCore:

<feImage> referencing local elements are currently rendered into an ImageBuffer
by SVGFEImageElement, using the local coordinates of the referenced renderer.

This approach is buggy and should be avoided, by moving the rendering fully
into SVGFEImage, which takes care of respecting the correct transformations.

This fixes <feImage> + local references, which currently breaks two tests in trunk.
Covered by existing tests.

* rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
(WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion):
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::build):
* svg/graphics/filters/SVGFEImage.cpp:
(WebCore::FEImage::FEImage):
(WebCore::FEImage::createWithImage):
(WebCore::FEImage::createWithIRIReference):
(WebCore::FEImage::determineAbsolutePaintRect):
(WebCore::FEImage::referencedRenderer):
(WebCore::FEImage::platformApplySoftware):
(WebCore::FEImage::externalRepresentation):
* svg/graphics/filters/SVGFEImage.h:
(WebCore::FEImage::~FEImage):
* svg/graphics/filters/SVGFilter.h:
(WebCore::SVGFilter::absoluteTransform):

LayoutTests:

Update svg/filters/feImage-reference-* results, which are fixed now.

* platform/chromium/test_expectations.txt : Updated.
* platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png: Update for marginal change.
* svg/filters/feImage-reference-invalidation-expected.png:
* svg/filters/feImage-reference-svg-primitive-expected.png:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (105611 => 105612)


--- trunk/LayoutTests/ChangeLog	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/LayoutTests/ChangeLog	2012-01-23 12:42:42 UTC (rev 105612)
@@ -1,3 +1,17 @@
+2012-01-23  Nikolas Zimmermann  <[email protected]>
+
+        <feImage> has problems referencing local elements
+        https://bugs.webkit.org/show_bug.cgi?id=76800
+
+        Reviewed by Zoltan Herczeg.
+
+        Update svg/filters/feImage-reference-* results, which are fixed now.
+
+        * platform/chromium/test_expectations.txt : Updated.
+        * platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png: Update for marginal change.
+        * svg/filters/feImage-reference-invalidation-expected.png:
+        * svg/filters/feImage-reference-svg-primitive-expected.png:
+
 2012-01-23  Csaba Osztrogonác  <[email protected]>
 
         WebKit fails IETC composition event types

Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (105611 => 105612)


--- trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt	2012-01-23 12:42:42 UTC (rev 105612)
@@ -3923,6 +3923,11 @@
 // Just needs a rebaseline.
 BUGWK76780 : svg/filters/feImage-preserveAspectratio.svg = IMAGE+TEXT
 
+// Just needs a rebaseline.
+BUGWK76800 : svg/W3C-SVG-1.1/filters-composite-02-b.svg = IMAGE
+BUGWK76800 : svg/filters/feImage-reference-invalidation.svg = IMAGE
+BUGWK76800 : svg/filters/feImage-reference-svg-primitive.svg = IMAGE
+
 // Change error (misspelling) underlines from Windows look to Mac look.
 BUG_CARYCLARK MAC : editing/deleting/delete-3928305-fix.html = IMAGE
 BUG_CARYCLARK MAC : editing/deleting/delete-3959464-fix.html = IMAGE

Modified: trunk/LayoutTests/platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/svg/filters/feImage-reference-invalidation-expected.png


(Binary files differ)

Modified: trunk/LayoutTests/svg/filters/feImage-reference-svg-primitive-expected.png


(Binary files differ)

Modified: trunk/Source/WebCore/ChangeLog (105611 => 105612)


--- trunk/Source/WebCore/ChangeLog	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/Source/WebCore/ChangeLog	2012-01-23 12:42:42 UTC (rev 105612)
@@ -1,5 +1,38 @@
 2012-01-23  Nikolas Zimmermann  <[email protected]>
 
+        <feImage> has problems referencing local elements
+        https://bugs.webkit.org/show_bug.cgi?id=76800
+
+        Reviewed by Zoltan Herczeg.
+
+        <feImage> referencing local elements are currently rendered into an ImageBuffer
+        by SVGFEImageElement, using the local coordinates of the referenced renderer.
+
+        This approach is buggy and should be avoided, by moving the rendering fully
+        into SVGFEImage, which takes care of respecting the correct transformations.
+
+        This fixes <feImage> + local references, which currently breaks two tests in trunk.
+        Covered by existing tests.
+
+        * rendering/svg/RenderSVGResourceFilterPrimitive.cpp:
+        (WebCore::RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion):
+        * svg/SVGFEImageElement.cpp:
+        (WebCore::SVGFEImageElement::build):
+        * svg/graphics/filters/SVGFEImage.cpp:
+        (WebCore::FEImage::FEImage):
+        (WebCore::FEImage::createWithImage):
+        (WebCore::FEImage::createWithIRIReference):
+        (WebCore::FEImage::determineAbsolutePaintRect):
+        (WebCore::FEImage::referencedRenderer):
+        (WebCore::FEImage::platformApplySoftware):
+        (WebCore::FEImage::externalRepresentation):
+        * svg/graphics/filters/SVGFEImage.h:
+        (WebCore::FEImage::~FEImage):
+        * svg/graphics/filters/SVGFilter.h:
+        (WebCore::SVGFilter::absoluteTransform):
+
+2012-01-23  Nikolas Zimmermann  <[email protected]>
+
         Not reviewed. Fix Mac build, by exporting a new symbol.
 
         * WebCore.exp.in:

Modified: trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp (105611 => 105612)


--- trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp	2012-01-23 12:42:42 UTC (rev 105612)
@@ -91,7 +91,7 @@
         subregion.setHeight(uniteRect.height());
     effect->setFilterPrimitiveSubregion(subregion);
 
-    FloatRect absoluteSubregion = filter->mapLocalRectToAbsoluteRect(subregion);
+    FloatRect absoluteSubregion = filter->absoluteTransform().mapRect(subregion);
     FloatSize filterResolution = filter->filterResolution();
     absoluteSubregion.scale(filterResolution.width(), filterResolution.height());
 

Modified: trunk/Source/WebCore/svg/SVGFEImageElement.cpp (105611 => 105612)


--- trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/Source/WebCore/svg/SVGFEImageElement.cpp	2012-01-23 12:42:42 UTC (rev 105612)
@@ -33,7 +33,6 @@
 #include "RenderObject.h"
 #include "RenderSVGResource.h"
 #include "SVGElementInstance.h"
-#include "SVGImageBufferTools.h"
 #include "SVGNames.h"
 #include "SVGPreserveAspectRatio.h"
 
@@ -183,27 +182,9 @@
     if (!m_cachedImage && !m_targetImage)
         requestImageResource();
 
-    if (!m_cachedImage && !m_targetImage) {
-        Element* hrefElement = SVGURIReference::targetElementFromIRIString(href(), document());
-        if (!hrefElement || !hrefElement->isSVGElement())
-            return 0;
-
-        RenderObject* renderer = hrefElement->renderer();
-        if (!renderer)
-            return 0;
-
-        IntRect targetRect = enclosingIntRect(renderer->objectBoundingBox());
-
-        if (targetRect.isEmpty())
-            return 0;
-
-        m_targetImage = ImageBuffer::create(targetRect.size(), ColorSpaceLinearRGB);
-
-        AffineTransform contentTransformation;
-        SVGImageBufferTools::renderSubtreeToImageBuffer(m_targetImage.get(), renderer, contentTransformation);
-    }
-
-    return FEImage::create(filter, m_targetImage ? m_targetImage->copyImage(CopyBackingStore) : m_cachedImage->imageForRenderer(renderer()), preserveAspectRatio());
+    if (!m_cachedImage && !m_targetImage)
+        return FEImage::createWithIRIReference(filter, document(), href(), preserveAspectRatio());
+    return FEImage::createWithImage(filter, m_cachedImage->imageForRenderer(renderer()), preserveAspectRatio());
 }
 
 void SVGFEImageElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp (105611 => 105612)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.cpp	2012-01-23 12:42:42 UTC (rev 105612)
@@ -28,8 +28,12 @@
 #include "AffineTransform.h"
 #include "Filter.h"
 #include "GraphicsContext.h"
+#include "RenderObject.h"
 #include "RenderTreeAsText.h"
+#include "SVGFilter.h"
+#include "SVGImageBufferTools.h"
 #include "SVGPreserveAspectRatio.h"
+#include "SVGURIReference.h"
 #include "TextStream.h"
 
 namespace WebCore {
@@ -37,19 +41,37 @@
 FEImage::FEImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio)
     : FilterEffect(filter)
     , m_image(image)
+    , m_document(0)
     , m_preserveAspectRatio(preserveAspectRatio)
 {
 }
 
-PassRefPtr<FEImage> FEImage::create(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio)
+FEImage::FEImage(Filter* filter, Document* document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio)
+    : FilterEffect(filter)
+    , m_document(document)
+    , m_href(href)
+    , m_preserveAspectRatio(preserveAspectRatio)
 {
+}
+
+PassRefPtr<FEImage> FEImage::createWithImage(Filter* filter, PassRefPtr<Image> image, const SVGPreserveAspectRatio& preserveAspectRatio)
+{
     return adoptRef(new FEImage(filter, image, preserveAspectRatio));
 }
 
+PassRefPtr<FEImage> FEImage::createWithIRIReference(Filter* filter, Document* document, const String& href, const SVGPreserveAspectRatio& preserveAspectRatio)
+{
+    return adoptRef(new FEImage(filter, document, href, preserveAspectRatio));
+}
+
 void FEImage::determineAbsolutePaintRect()
 {
-    ASSERT(m_image);
-    FloatRect srcRect(FloatPoint(), m_image->size());
+    FloatRect srcRect;
+    if (m_image)
+        srcRect.setSize(m_image->size());
+    else if (RenderObject* renderer = referencedRenderer())
+        srcRect = static_cast<SVGFilter*>(filter())->absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates());
+
     FloatRect paintRect(m_absoluteSubregion);
     m_preserveAspectRatio.transformRect(paintRect, srcRect);
     if (clipsToBounds())
@@ -59,15 +81,37 @@
     setAbsolutePaintRect(enclosingIntRect(paintRect));
 }
 
+RenderObject* FEImage::referencedRenderer() const
+{
+    if (!m_document)
+        return 0;
+    Element* hrefElement = SVGURIReference::targetElementFromIRIString(m_href, m_document);
+    if (!hrefElement || !hrefElement->isSVGElement())
+        return 0;
+    return hrefElement->renderer();
+}
+
 void FEImage::platformApplySoftware()
 {
-    if (!m_image.get())
+    RenderObject* renderer = referencedRenderer();
+    if (!m_image && !renderer)
         return;
 
     ImageBuffer* resultImage = createImageBufferResult();
     if (!resultImage)
         return;
 
+    if (renderer) {
+        const AffineTransform& absoluteTransform = static_cast<SVGFilter*>(filter())->absoluteTransform();
+        resultImage->context()->concatCTM(absoluteTransform);
+
+        AffineTransform contentTransformation;
+        SVGImageBufferTools::renderSubtreeToImageBuffer(resultImage, renderer, contentTransformation);
+
+        resultImage->context()->concatCTM(absoluteTransform.inverse());
+        return;
+    }
+
     FloatRect srcRect(FloatPoint(), m_image->size());
     FloatRect destRect(m_absoluteSubregion);
     m_preserveAspectRatio.transformRect(destRect, srcRect);
@@ -84,8 +128,11 @@
 
 TextStream& FEImage::externalRepresentation(TextStream& ts, int indent) const
 {
-    ASSERT(m_image);
-    IntSize imageSize = m_image->size();
+    IntSize imageSize;
+    if (m_image)
+        imageSize = m_image->size();
+    else if (RenderObject* renderer = referencedRenderer())
+        imageSize = enclosingIntRect(renderer->repaintRectInLocalCoordinates()).size();
     writeIndent(ts, indent);
     ts << "[feImage";
     FilterEffect::externalRepresentation(ts);

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h (105611 => 105612)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFEImage.h	2012-01-23 12:42:42 UTC (rev 105612)
@@ -29,11 +29,14 @@
 
 namespace WebCore {
 
+class Document;
 class Image;
+class RenderObject;
 
 class FEImage : public FilterEffect {
 public:
-    static PassRefPtr<FEImage> create(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&);
+    static PassRefPtr<FEImage> createWithImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&);
+    static PassRefPtr<FEImage> createWithIRIReference(Filter*, Document*, const String&, const SVGPreserveAspectRatio&);
 
     void setAbsoluteSubregion(const FloatRect& absoluteSubregion) { m_absoluteSubregion = absoluteSubregion; }
 
@@ -47,9 +50,14 @@
     virtual TextStream& externalRepresentation(TextStream&, int indention) const;
     
 private:
+    virtual ~FEImage() { }
     FEImage(Filter*, PassRefPtr<Image>, const SVGPreserveAspectRatio&);
+    FEImage(Filter*, Document*, const String&, const SVGPreserveAspectRatio&);
+    RenderObject* referencedRenderer() const;
 
     RefPtr<Image> m_image;
+    Document* m_document;
+    String m_href;
     SVGPreserveAspectRatio m_preserveAspectRatio;
     FloatRect m_absoluteSubregion;
 };

Modified: trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h (105611 => 105612)


--- trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2012-01-23 12:39:31 UTC (rev 105611)
+++ trunk/Source/WebCore/svg/graphics/filters/SVGFilter.h	2012-01-23 12:42:42 UTC (rev 105612)
@@ -41,7 +41,7 @@
     virtual FloatRect filterRegion() const { return m_absoluteFilterRegion; }
 
     virtual FloatPoint mapAbsolutePointToLocalPoint(const FloatPoint& point) const { return m_absoluteTransform.inverse().mapPoint(point); }
-    FloatRect mapLocalRectToAbsoluteRect(const FloatRect& rect) const { return m_absoluteTransform.mapRect(rect); }
+    const AffineTransform& absoluteTransform() const { return m_absoluteTransform; }
 
     virtual float applyHorizontalScale(float value) const;
     virtual float applyVerticalScale(float value) const;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to