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:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@105612
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2012-01-23 Nikolas Zimmermann <nzimmermann@rim.com>
+
+ <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 <ossy@webkit.org>
WebKit fails IETC composition event types
// 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
2012-01-23 Nikolas Zimmermann <nzimmermann@rim.com>
+ <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 <nzimmermann@rim.com>
+
Not reviewed. Fix Mac build, by exporting a new symbol.
* WebCore.exp.in:
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());
#include "RenderObject.h"
#include "RenderSVGResource.h"
#include "SVGElementInstance.h"
-#include "SVGImageBufferTools.h"
#include "SVGNames.h"
#include "SVGPreserveAspectRatio.h"
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
#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 {
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())
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);
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);
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; }
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;
};
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;