Commit aaef148b authored by krit@webkit.org's avatar krit@webkit.org
Browse files

2010-01-06 Dirk Schulze <krit@webkit.org>

        Reviewed by Nikolas Zimmermann.

        SVG feImage support
        https://bugs.webkit.org/show_bug.cgi?id=31905

        This implements the SVG Filter effect feImage with support of fragment urls.
        It also includes a bug fix for feComposite. feComposite didn't cover values
        bigger than 255 correctly on composite oeprator arithmetic.

        Tests: There are already many feImage tests in trunk. They just needed updated
               pixel test results.
               The feComposite bug is covered by svg/W3C-SVG-1.1/filters-composite-02-b.svg
               and depends on feImage.

        * platform/graphics/filters/FEComposite.cpp:
        (WebCore::arithmetic):
        * rendering/RenderSVGImage.cpp:
        (WebCore::RenderSVGImage::paint):
        * rendering/RenderSVGImage.h:
        * svg/SVGFEImageElement.cpp:
        (WebCore::SVGFEImageElement::requestImageResource):
        (WebCore::SVGFEImageElement::parseMappedAttribute):
        (WebCore::SVGFEImageElement::notifyFinished):
        (WebCore::SVGFEImageElement::build):
        * svg/SVGFEImageElement.h:
        * svg/SVGFEImageElement.idl:
        * svg/SVGPreserveAspectRatio.cpp:
        (WebCore::SVGPreserveAspectRatio::transformRect):
        * svg/SVGPreserveAspectRatio.h:
        * svg/graphics/filters/SVGFEImage.cpp:
        (WebCore::FEImage::FEImage):
        (WebCore::FEImage::create):
        (WebCore::FEImage::apply):
        * svg/graphics/filters/SVGFEImage.h:

2010-01-06  Dirk Schulze  <krit@webkit.org>

        Reviewed by Nikolas Zimmermann.

        SVG feImage support
        https://bugs.webkit.org/show_bug.cgi?id=31905

        The implementation of feImage requires pixel test result updates of the already
        available tests.

        There is also an update for svg/filters/feComposite.svg, since the patch also
        fixed a bug in feComposite.

        * platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.checksum:
        * platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png:
        * platform/mac/svg/W3C-SVG-1.1/filters-displace-01-f-expected.checksum:
        * platform/mac/svg/W3C-SVG-1.1/filters-displace-01-f-expected.png:
        * platform/mac/svg/W3C-SVG-1.1/filters-image-01-b-expected.checksum:
        * platform/mac/svg/W3C-SVG-1.1/filters-image-01-b-expected.png:
        * platform/mac/svg/custom/feDisplacementMap-01-expected.checksum:
        * platform/mac/svg/custom/feDisplacementMap-01-expected.png:
        * platform/mac/svg/filters/feComposite-expected.checksum:
        * platform/mac/svg/filters/feComposite-expected.png:
        * platform/mac/svg/webarchive/svg-feimage-subresources-expected.checksum:
        * platform/mac/svg/webarchive/svg-feimage-subresources-expected.png:

2010-01-06  Dirk Schulze  <krit@webkit.org>

        Reviewed by Nikolas Zimmermann.

        SVG feImage support
        https://bugs.webkit.org/show_bug.cgi?id=31905

        Update SVG status page. We support feDisplacementMap and feImage now.

        * projects/svg/status.xml:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@52865 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent b74c1392
2010-01-06 Dirk Schulze <krit@webkit.org>
Reviewed by Nikolas Zimmermann.
SVG feImage support
https://bugs.webkit.org/show_bug.cgi?id=31905
The implementation of feImage requires pixel test result updates of the already
available tests.
There is also an update for svg/filters/feComposite.svg, since the patch also
fixed a bug in feComposite.
* platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.checksum:
* platform/mac/svg/W3C-SVG-1.1/filters-composite-02-b-expected.png:
* platform/mac/svg/W3C-SVG-1.1/filters-displace-01-f-expected.checksum:
* platform/mac/svg/W3C-SVG-1.1/filters-displace-01-f-expected.png:
* platform/mac/svg/W3C-SVG-1.1/filters-image-01-b-expected.checksum:
* platform/mac/svg/W3C-SVG-1.1/filters-image-01-b-expected.png:
* platform/mac/svg/custom/feDisplacementMap-01-expected.checksum:
* platform/mac/svg/custom/feDisplacementMap-01-expected.png:
* platform/mac/svg/filters/feComposite-expected.checksum:
* platform/mac/svg/filters/feComposite-expected.png:
* platform/mac/svg/webarchive/svg-feimage-subresources-expected.checksum:
* platform/mac/svg/webarchive/svg-feimage-subresources-expected.png:
2010-01-06 Darin Adler <darin@apple.com>
 
Added file James Robinson provided to go with his fix for
595cf6946aa045acc21ed50e49871010
\ No newline at end of file
4e2d58b2588a2a7b8d42e789a80f789f
\ No newline at end of file
a5b60846615b1ff8ccd1bbb5062c6fe5
\ No newline at end of file
b6c63dd5fe1fda01e3ff9b0dfd771915
\ No newline at end of file
5a1e5687cc46137b116c062c175d83d5
\ No newline at end of file
cfb233bae17cc624073e47952c53e490
\ No newline at end of file
37725a2315328ea128fc2cfe3549a4f9
\ No newline at end of file
c13733cd61a1b84ab863558aa67ee47b
\ No newline at end of file
2393c34443caa35be741e4cc3e05edd2
\ No newline at end of file
d0fabba10fec772a87a338fa3bf1b627
\ No newline at end of file
853de00567d121bea0b7bece66a5d61c
\ No newline at end of file
c6ab9fc121db160df3116601d024db23
\ No newline at end of file
2010-01-06 Dirk Schulze <krit@webkit.org>
Reviewed by Nikolas Zimmermann.
SVG feImage support
https://bugs.webkit.org/show_bug.cgi?id=31905
This implements the SVG Filter effect feImage with support of fragment urls.
It also includes a bug fix for feComposite. feComposite didn't cover values
bigger than 255 correctly on composite oeprator arithmetic.
Tests: There are already many feImage tests in trunk. They just needed updated
pixel test results.
The feComposite bug is covered by svg/W3C-SVG-1.1/filters-composite-02-b.svg
and depends on feImage.
* platform/graphics/filters/FEComposite.cpp:
(WebCore::arithmetic):
* rendering/RenderSVGImage.cpp:
(WebCore::RenderSVGImage::paint):
* rendering/RenderSVGImage.h:
* svg/SVGFEImageElement.cpp:
(WebCore::SVGFEImageElement::requestImageResource):
(WebCore::SVGFEImageElement::parseMappedAttribute):
(WebCore::SVGFEImageElement::notifyFinished):
(WebCore::SVGFEImageElement::build):
* svg/SVGFEImageElement.h:
* svg/SVGFEImageElement.idl:
* svg/SVGPreserveAspectRatio.cpp:
(WebCore::SVGPreserveAspectRatio::transformRect):
* svg/SVGPreserveAspectRatio.h:
* svg/graphics/filters/SVGFEImage.cpp:
(WebCore::FEImage::FEImage):
(WebCore::FEImage::create):
(WebCore::FEImage::apply):
* svg/graphics/filters/SVGFEImage.h:
2010-01-06 Yong Li <yoli@rim.com>
 
Reviewed by Darin Adler.
......@@ -111,9 +111,7 @@ inline void arithmetic(const RefPtr<CanvasPixelArray>& srcPixelArrayA, CanvasPix
unsigned char i1 = srcPixelArrayA->get(pixelOffset + channel);
unsigned char i2 = srcPixelArrayB->get(pixelOffset + channel);
unsigned char result = scaledK1 * i1 * i2 + k2 * i1 + k3 * i2 + scaledK4;
if (channel == 3 && i1 == 0 && i2 == 0)
result = 0;
double result = scaledK1 * i1 * i2 + k2 * i1 + k3 * i2 + scaledK4;
srcPixelArrayB->set(pixelOffset + channel, result);
}
}
......
......@@ -48,81 +48,6 @@ RenderSVGImage::RenderSVGImage(SVGImageElement* impl)
{
}
void RenderSVGImage::adjustRectsForAspectRatio(FloatRect& destRect, FloatRect& srcRect, const SVGPreserveAspectRatio& aspectRatio)
{
float origDestWidth = destRect.width();
float origDestHeight = destRect.height();
if (aspectRatio.meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET) {
float widthToHeightMultiplier = srcRect.height() / srcRect.width();
if (origDestHeight > (origDestWidth * widthToHeightMultiplier)) {
destRect.setHeight(origDestWidth * widthToHeightMultiplier);
switch (aspectRatio.align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
destRect.setY(destRect.y() + origDestHeight / 2.0f - destRect.height() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
destRect.setY(destRect.y() + origDestHeight - destRect.height());
break;
}
}
if (origDestWidth > (origDestHeight / widthToHeightMultiplier)) {
destRect.setWidth(origDestHeight / widthToHeightMultiplier);
switch (aspectRatio.align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
destRect.setX(destRect.x() + origDestWidth / 2.0f - destRect.width() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
destRect.setX(destRect.x() + origDestWidth - destRect.width());
break;
}
}
} else if (aspectRatio.meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE) {
float widthToHeightMultiplier = srcRect.height() / srcRect.width();
// if the destination height is less than the height of the image we'll be drawing
if (origDestHeight < (origDestWidth * widthToHeightMultiplier)) {
float destToSrcMultiplier = srcRect.width() / destRect.width();
srcRect.setHeight(destRect.height() * destToSrcMultiplier);
switch (aspectRatio.align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
srcRect.setY(destRect.y() + image()->height() / 2.0f - srcRect.height() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMINYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
srcRect.setY(destRect.y() + image()->height() - srcRect.height());
break;
}
}
// if the destination width is less than the width of the image we'll be drawing
if (origDestWidth < (origDestHeight / widthToHeightMultiplier)) {
float destToSrcMultiplier = srcRect.height() / destRect.height();
srcRect.setWidth(destRect.width() * destToSrcMultiplier);
switch (aspectRatio.align()) {
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMAX:
srcRect.setX(destRect.x() + image()->width() / 2.0f - srcRect.width() / 2.0f);
break;
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMIN:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMID:
case SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMAXYMAX:
srcRect.setX(destRect.x() + image()->width() - srcRect.width());
break;
}
}
}
}
void RenderSVGImage::layout()
{
ASSERT(needsLayout());
......@@ -165,7 +90,7 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
SVGImageElement* imageElt = static_cast<SVGImageElement*>(node());
if (imageElt->preserveAspectRatio().align() != SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE)
adjustRectsForAspectRatio(destRect, srcRect, imageElt->preserveAspectRatio());
imageElt->preserveAspectRatio().transformRect(destRect, srcRect);
paintInfo.context->drawImage(image(), DeviceColorSpace, destRect, srcRect);
}
......
......@@ -59,7 +59,6 @@ namespace WebCore {
virtual void addFocusRingRects(Vector<IntRect>&, int tx, int ty);
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
void adjustRectsForAspectRatio(FloatRect& destRect, FloatRect& srcRect, const SVGPreserveAspectRatio&);
virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
......
/*
Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
2004, 2005 Rob Buis <buis@kde.org>
2010 Dirk Schulze <krit@webkit.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
......@@ -31,6 +32,7 @@
#include "SVGLength.h"
#include "SVGNames.h"
#include "SVGPreserveAspectRatio.h"
#include "SVGRenderSupport.h"
#include "SVGResourceFilter.h"
namespace WebCore {
......@@ -52,6 +54,23 @@ SVGFEImageElement::~SVGFEImageElement()
m_cachedImage->removeClient(this);
}
void SVGFEImageElement::requestImageResource()
{
if (m_cachedImage) {
m_cachedImage->removeClient(this);
m_cachedImage = 0;
}
Element* hrefElement = document()->getElementById(SVGURIReference::getTarget(href()));
if (hrefElement && hrefElement->isSVGElement() && hrefElement->renderer())
return;
m_cachedImage = ownerDocument()->docLoader()->requestImage(href());
if (m_cachedImage)
m_cachedImage->addClient(this);
}
void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr)
{
const String& value = attr->value();
......@@ -59,14 +78,7 @@ void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr)
SVGPreserveAspectRatio::parsePreserveAspectRatio(this, value);
else {
if (SVGURIReference::parseMappedAttribute(attr)) {
if (!href().startsWith("#")) {
// FIXME: this code needs to special-case url fragments and later look them up using getElementById instead of loading them here
if (m_cachedImage)
m_cachedImage->removeClient(this);
m_cachedImage = ownerDocument()->docLoader()->requestImage(href());
if (m_cachedImage)
m_cachedImage->addClient(this);
}
requestImageResource();
return;
}
if (SVGLangSpace::parseMappedAttribute(attr))
......@@ -80,14 +92,27 @@ void SVGFEImageElement::parseMappedAttribute(MappedAttribute* attr)
void SVGFEImageElement::notifyFinished(CachedResource*)
{
SVGStyledElement::invalidateResourcesInAncestorChain();
}
bool SVGFEImageElement::build(SVGResourceFilter* filterResource)
{
if (!m_cachedImage)
return false;
if (!m_cachedImage && !m_targetImage) {
Element* hrefElement = document()->getElementById(SVGURIReference::getTarget(href()));
if (!hrefElement || !hrefElement->isSVGElement())
return false;
RenderObject* renderer = hrefElement->renderer();
if (!renderer)
return false;
IntRect targetRect = enclosingIntRect(renderer->objectBoundingBox());
m_targetImage = ImageBuffer::create(targetRect.size(), LinearRGB);
renderSubtreeToImage(m_targetImage.get(), renderer);
}
RefPtr<FilterEffect> effect = FEImage::create(m_cachedImage.get());
RefPtr<FilterEffect> effect = FEImage::create(m_targetImage ? m_targetImage->image() : m_cachedImage->image(), preserveAspectRatio());
filterResource->addFilterEffect(this, effect.release());
return true;
......
......@@ -23,12 +23,13 @@
#if ENABLE(SVG) && ENABLE(FILTERS)
#include "CachedResourceHandle.h"
#include "SVGFilterPrimitiveStandardAttributes.h"
#include "SVGURIReference.h"
#include "SVGLangSpace.h"
#include "ImageBuffer.h"
#include "SVGExternalResourcesRequired.h"
#include "SVGFEImage.h"
#include "SVGFilterPrimitiveStandardAttributes.h"
#include "SVGLangSpace.h"
#include "SVGPreserveAspectRatio.h"
#include "SVGURIReference.h"
namespace WebCore {
......@@ -48,6 +49,8 @@ namespace WebCore {
virtual bool build(SVGResourceFilter*);
private:
void requestImageResource();
ANIMATED_PROPERTY_DECLARATIONS(SVGFEImageElement, SVGNames::feImageTagString, SVGNames::preserveAspectRatioAttrString, SVGPreserveAspectRatio, PreserveAspectRatio, preserveAspectRatio)
// SVGURIReference
......@@ -59,6 +62,7 @@ namespace WebCore {
ExternalResourcesRequired, externalResourcesRequired)
CachedResourceHandle<CachedImage> m_cachedImage;
OwnPtr<ImageBuffer> m_targetImage;
};
} // namespace WebCore
......
......@@ -26,10 +26,11 @@
module svg {
interface [Conditional=SVG&FILTERS] SVGFEImageElement : SVGElement,
SVGURIReference,
SVGLangSpace,
SVGExternalResourcesRequired,
SVGFilterPrimitiveStandardAttributes {
SVGURIReference,
SVGLangSpace,
SVGExternalResourcesRequired,
SVGFilterPrimitiveStandardAttributes {
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment