[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

krit at webkit.org krit at webkit.org
Wed Apr 7 23:54:12 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 5adf763c102729689d7d5a30671afd8ec37ebad5
Author: krit at webkit.org <krit at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Nov 23 16:15:24 2009 +0000

    2009-11-23  Dirk Schulze  <krit at webkit.org>
    
            Reviewed by Nikolas Zimmermann.
    
            This is the implementation of the filterRes attribute. It
            helps the SVG developer to set the quality of a filter by
            giving the width or height of filter.
            This patch also sets the filter resolution to lower values
            if a intermediate ImageBuffer size is bigger than the given
            maximal size.
            The maximal size is set to 5000x5000 by default. This is a
            subjectiv decission. Everthing greater than this values gets
            sensible slower. Values of 10000x10000 crashed on WebKitGtk.
            For mobil devices a maximum size of 100x100 or 200x200 seems
            to be reasonable.
            The important fact on filter resolution is, that the output
            size is still the size given by the <filter> element.
    
            Tests: svg/filters/big-sized-filter-2.svg
                   svg/filters/big-sized-filter.svg
                   svg/filters/filterRes.svg
    
            * platform/graphics/FloatRect.cpp:
            (WebCore::FloatRect::scale): Add the abbility to scale a rect by x and y.
            * platform/graphics/FloatRect.h:
            (WebCore::FloatRect::scale): Add the abbility to scale a rect by x and y.
            * platform/graphics/cairo/GraphicsContextCairo.cpp:
            (WebCore::GraphicsContext::createPlatformShadow): Use scaledSubRegion for
            calculation.
            * platform/graphics/filters/FEBlend.cpp:
            (WebCore::FEBlend::apply): Use scaledSubRegion for effect intern calculations.
            * platform/graphics/filters/FEColorMatrix.cpp:
            (WebCore::FEColorMatrix::apply): Use scaledSubRegion for effect intern calculations.
            * platform/graphics/filters/FEComponentTransfer.cpp:
            (WebCore::FEComponentTransfer::apply): Use scaledSubRegion for effect intern
            calculations.
            * platform/graphics/filters/FEComposite.cpp:
            (WebCore::FEComposite::apply): Use scaledSubRegion for effect intern calculations.
            * platform/graphics/filters/FEGaussianBlur.cpp:
            (WebCore::FEGaussianBlur::apply): Use scaledSubRegion for effect intern calculations.
            * platform/graphics/filters/Filter.h: Add the abbility to change the quality
            of a filter output.
            (WebCore::Filter::filterResolution):
            (WebCore::Filter::setFilterResolution):
            (WebCore::Filter::calculateEffectSubRegion): Calculates the correct subRegion
            as well as the scaledSubRegion. It also searches for the biggest effect size.
            We have to change the filter resolution, if one intermediate ImageBuffer size
            doesn't fit in the maximal image size.
            * platform/graphics/filters/FilterEffect.cpp:
            (WebCore::FilterEffect::calculateDrawingIntRect): Use scaledSubRegion to get
            the right part of a previous effect result.
            (WebCore::FilterEffect::calculateDrawingRect): Use scaledSubRegion to get
            the right part of a previous effect result.
            (WebCore::FilterEffect::getEffectContext): Use scaledSubRegion to create
            a new intermediate ImageBuffer for the result of the current effect.
            * platform/graphics/filters/FilterEffect.h:
            (WebCore::FilterEffect::scaledSubRegion): The scaled subRegion of a the
            filter effect.
            (WebCore::FilterEffect::setScaledSubRegion):
            (WebCore::FilterEffect::effectBoundaries): The original values of the
            EffectElement for a second subRegion calculation.
            (WebCore::FilterEffect::setEffectBoundaries):
            * platform/graphics/filters/ImageBufferFilter.cpp:
            (WebCore::ImageBufferFilter::ImageBufferFilter): Set the scale factor to one.
            * platform/graphics/filters/ImageBufferFilter.h:
            (WebCore::ImageBufferFilter::maxImageSize):
            (WebCore::ImageBufferFilter::calculateEffectSubRegion):
            * platform/graphics/filters/SourceAlpha.cpp:
            (WebCore::SourceAlpha::calculateEffectRect): Use scaledSubRegion for effect
            intern calculations.
            * platform/graphics/filters/SourceGraphic.cpp:
            (WebCore::SourceGraphic::calculateEffectRect): Use scaledSubRegion for effect
            intern calculations.
            * svg/SVGFilterElement.cpp:
            (WebCore::SVGFilterElement::parseMappedAttribute): Parse filterRes attribute.
            (WebCore::SVGFilterElement::buildFilter): Give SVGResourceFilter the current
            filterResolution.
            * svg/SVGFilterPrimitiveStandardAttributes.cpp:
            (WebCore::SVGFilterPrimitiveStandardAttributes::setStandardAttributes): Save
            values to effectBoundaries of the filter effect
            * svg/graphics/SVGResourceFilter.cpp:
            (WebCore::SVGResourceFilter::SVGResourceFilter):
            (WebCore::shouldProcessFilter): Return signal if a neccessary value is zero.
            (WebCore::SVGResourceFilter::fitsInMaximumImageSize): Checks if the given size
            fits into the maximal image size, modifys scale factors if not and return a
            bool: fits.
            (WebCore::SVGResourceFilter::prepareFilter): Scale the SourceImage to
            filterResolution (given by FilterElement or calculated on to big image sizes).
            Set the scale level to SVGFilter.
            (WebCore::SVGResourceFilter::applyFilter): Don't apply filters if shouldProcessFilter
            is wrong.
            * svg/graphics/SVGResourceFilter.h:
            (WebCore::SVGResourceFilter::setFilterResolution): FilterResolution of FilterElement.
            (WebCore::SVGResourceFilter::setHasFilterResolution): Does FilterElement provides
            a FilterResolution?
            (WebCore::SVGResourceFilter::scaleX): Current scale factor for horizontal.
            (WebCore::SVGResourceFilter::scaleY): Current scale factor for vertical.
            * svg/graphics/filters/SVGFEDisplacementMap.cpp:
            (WebCore::FEDisplacementMap::apply): Use scaledSubRegion for effect intern calculations.
            Kernel values are scaled to current filter resolution too.
            * svg/graphics/filters/SVGFEFlood.cpp:
            (WebCore::FEFlood::apply): Use scaledSubRegion for effect intern calculations.
            * svg/graphics/filters/SVGFEMerge.cpp:
            (WebCore::FEMerge::apply): Use scaledSubRegion for effect intern calculations.
            Kernel values are scaled to current filter resolution too.
            * svg/graphics/filters/SVGFEMorphology.cpp:
            (WebCore::FEMorphology::apply): Use scaledSubRegion for effect intern calculations.
            Kernel values are scaled to current filter resolution too.
            * svg/graphics/filters/SVGFEOffset.cpp:
            (WebCore::FEOffset::apply): Use scaledSubRegion for effect intern calculations.
            * svg/graphics/filters/SVGFETile.cpp:
            (WebCore::FETile::apply): Use scaledSubRegion for effect intern calculations.
            * svg/graphics/filters/SVGFilter.cpp:
            (WebCore::SVGFilter::calculateEffectSubRegion): Calculate subRegion for LayoutTests,
            scaledSubRegion according to the current filterResolution and get the maximal image size.
            * svg/graphics/filters/SVGFilter.h:
            (WebCore::SVGFilter::effectBoundingBoxMode): Original values of the FilterElement.
            (WebCore::SVGFilter::filterRegion): Use virtual for clarification.
            (WebCore::SVGFilter::sourceImageRect): Use virtual for clarification.
            (WebCore::SVGFilter::maxImageSize): Get the maximal image size.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51310 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 456078c..c7afde2 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,124 @@
+2009-11-23  Dirk Schulze  <krit at webkit.org>
+
+        Reviewed by Nikolas Zimmermann.
+
+        This is the implementation of the filterRes attribute. It
+        helps the SVG developer to set the quality of a filter by
+        giving the width or height of filter.
+        This patch also sets the filter resolution to lower values
+        if a intermediate ImageBuffer size is bigger than the given
+        maximal size.
+        The maximal size is set to 5000x5000 by default. This is a
+        subjectiv decission. Everthing greater than this values gets
+        sensible slower. Values of 10000x10000 crashed on WebKitGtk.
+        For mobil devices a maximum size of 100x100 or 200x200 seems
+        to be reasonable.
+        The important fact on filter resolution is, that the output
+        size is still the size given by the <filter> element.
+
+        Tests: svg/filters/big-sized-filter-2.svg
+               svg/filters/big-sized-filter.svg
+               svg/filters/filterRes.svg
+
+        * platform/graphics/FloatRect.cpp:
+        (WebCore::FloatRect::scale): Add the abbility to scale a rect by x and y.
+        * platform/graphics/FloatRect.h:
+        (WebCore::FloatRect::scale): Add the abbility to scale a rect by x and y.
+        * platform/graphics/cairo/GraphicsContextCairo.cpp:
+        (WebCore::GraphicsContext::createPlatformShadow): Use scaledSubRegion for
+        calculation.
+        * platform/graphics/filters/FEBlend.cpp:
+        (WebCore::FEBlend::apply): Use scaledSubRegion for effect intern calculations.
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrix::apply): Use scaledSubRegion for effect intern calculations.
+        * platform/graphics/filters/FEComponentTransfer.cpp:
+        (WebCore::FEComponentTransfer::apply): Use scaledSubRegion for effect intern
+        calculations.
+        * platform/graphics/filters/FEComposite.cpp:
+        (WebCore::FEComposite::apply): Use scaledSubRegion for effect intern calculations.
+        * platform/graphics/filters/FEGaussianBlur.cpp:
+        (WebCore::FEGaussianBlur::apply): Use scaledSubRegion for effect intern calculations.
+        * platform/graphics/filters/Filter.h: Add the abbility to change the quality
+        of a filter output.
+        (WebCore::Filter::filterResolution):
+        (WebCore::Filter::setFilterResolution):
+        (WebCore::Filter::calculateEffectSubRegion): Calculates the correct subRegion
+        as well as the scaledSubRegion. It also searches for the biggest effect size.
+        We have to change the filter resolution, if one intermediate ImageBuffer size
+        doesn't fit in the maximal image size.
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::calculateDrawingIntRect): Use scaledSubRegion to get
+        the right part of a previous effect result.
+        (WebCore::FilterEffect::calculateDrawingRect): Use scaledSubRegion to get
+        the right part of a previous effect result.
+        (WebCore::FilterEffect::getEffectContext): Use scaledSubRegion to create
+        a new intermediate ImageBuffer for the result of the current effect.
+        * platform/graphics/filters/FilterEffect.h:
+        (WebCore::FilterEffect::scaledSubRegion): The scaled subRegion of a the
+        filter effect.
+        (WebCore::FilterEffect::setScaledSubRegion):
+        (WebCore::FilterEffect::effectBoundaries): The original values of the
+        EffectElement for a second subRegion calculation.
+        (WebCore::FilterEffect::setEffectBoundaries):
+        * platform/graphics/filters/ImageBufferFilter.cpp:
+        (WebCore::ImageBufferFilter::ImageBufferFilter): Set the scale factor to one.
+        * platform/graphics/filters/ImageBufferFilter.h:
+        (WebCore::ImageBufferFilter::maxImageSize):
+        (WebCore::ImageBufferFilter::calculateEffectSubRegion):
+        * platform/graphics/filters/SourceAlpha.cpp:
+        (WebCore::SourceAlpha::calculateEffectRect): Use scaledSubRegion for effect
+        intern calculations.
+        * platform/graphics/filters/SourceGraphic.cpp:
+        (WebCore::SourceGraphic::calculateEffectRect): Use scaledSubRegion for effect
+        intern calculations.
+        * svg/SVGFilterElement.cpp:
+        (WebCore::SVGFilterElement::parseMappedAttribute): Parse filterRes attribute.
+        (WebCore::SVGFilterElement::buildFilter): Give SVGResourceFilter the current
+        filterResolution.
+        * svg/SVGFilterPrimitiveStandardAttributes.cpp:
+        (WebCore::SVGFilterPrimitiveStandardAttributes::setStandardAttributes): Save
+        values to effectBoundaries of the filter effect
+        * svg/graphics/SVGResourceFilter.cpp:
+        (WebCore::SVGResourceFilter::SVGResourceFilter):
+        (WebCore::shouldProcessFilter): Return signal if a neccessary value is zero.
+        (WebCore::SVGResourceFilter::fitsInMaximumImageSize): Checks if the given size
+        fits into the maximal image size, modifys scale factors if not and return a
+        bool: fits.
+        (WebCore::SVGResourceFilter::prepareFilter): Scale the SourceImage to
+        filterResolution (given by FilterElement or calculated on to big image sizes).
+        Set the scale level to SVGFilter.
+        (WebCore::SVGResourceFilter::applyFilter): Don't apply filters if shouldProcessFilter
+        is wrong.
+        * svg/graphics/SVGResourceFilter.h:
+        (WebCore::SVGResourceFilter::setFilterResolution): FilterResolution of FilterElement.
+        (WebCore::SVGResourceFilter::setHasFilterResolution): Does FilterElement provides
+        a FilterResolution?
+        (WebCore::SVGResourceFilter::scaleX): Current scale factor for horizontal.
+        (WebCore::SVGResourceFilter::scaleY): Current scale factor for vertical.
+        * svg/graphics/filters/SVGFEDisplacementMap.cpp:
+        (WebCore::FEDisplacementMap::apply): Use scaledSubRegion for effect intern calculations.
+        Kernel values are scaled to current filter resolution too.
+        * svg/graphics/filters/SVGFEFlood.cpp:
+        (WebCore::FEFlood::apply): Use scaledSubRegion for effect intern calculations.
+        * svg/graphics/filters/SVGFEMerge.cpp:
+        (WebCore::FEMerge::apply): Use scaledSubRegion for effect intern calculations.
+        Kernel values are scaled to current filter resolution too.
+        * svg/graphics/filters/SVGFEMorphology.cpp:
+        (WebCore::FEMorphology::apply): Use scaledSubRegion for effect intern calculations.
+        Kernel values are scaled to current filter resolution too.
+        * svg/graphics/filters/SVGFEOffset.cpp:
+        (WebCore::FEOffset::apply): Use scaledSubRegion for effect intern calculations.
+        * svg/graphics/filters/SVGFETile.cpp:
+        (WebCore::FETile::apply): Use scaledSubRegion for effect intern calculations.
+        * svg/graphics/filters/SVGFilter.cpp:
+        (WebCore::SVGFilter::calculateEffectSubRegion): Calculate subRegion for LayoutTests,
+        scaledSubRegion according to the current filterResolution and get the maximal image size.
+        * svg/graphics/filters/SVGFilter.h:
+        (WebCore::SVGFilter::effectBoundingBoxMode): Original values of the FilterElement. 
+        (WebCore::SVGFilter::filterRegion): Use virtual for clarification.
+        (WebCore::SVGFilter::sourceImageRect): Use virtual for clarification.
+        (WebCore::SVGFilter::maxImageSize): Get the maximal image size.
+
 2009-11-23  Simon Hausmann  <simon.hausmann at nokia.com>
 
         Reviewed by Kenneth Rohde Christiansen.
diff --git a/WebCore/platform/graphics/FloatRect.cpp b/WebCore/platform/graphics/FloatRect.cpp
index 532f719..7a54f21 100644
--- a/WebCore/platform/graphics/FloatRect.cpp
+++ b/WebCore/platform/graphics/FloatRect.cpp
@@ -102,12 +102,12 @@ void FloatRect::unite(const FloatRect& other)
     m_size.setHeight(b - t);
 }
 
-void FloatRect::scale(float s)
+void FloatRect::scale(float sx, float sy)
 {
-    m_location.setX(x() * s);
-    m_location.setY(y() * s);
-    m_size.setWidth(width() * s);
-    m_size.setHeight(height() * s);
+    m_location.setX(x() * sx);
+    m_location.setY(y() * sy);
+    m_size.setWidth(width() * sx);
+    m_size.setHeight(height() * sy);
 }
 
 IntRect enclosingIntRect(const FloatRect& rect)
diff --git a/WebCore/platform/graphics/FloatRect.h b/WebCore/platform/graphics/FloatRect.h
index 073f135..2dc854d 100644
--- a/WebCore/platform/graphics/FloatRect.h
+++ b/WebCore/platform/graphics/FloatRect.h
@@ -120,7 +120,8 @@ public:
         m_size.setHeight(m_size.height() + dy + dy);
     }
     void inflate(float d) { inflateX(d); inflateY(d); }
-    void scale(float s);
+    void scale(float s) { scale(s, s); }
+    void scale(float sx, float sy);
 
 #if PLATFORM(CG)
     FloatRect(const CGRect&);
diff --git a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
index 3f280d7..14034fd 100644
--- a/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
+++ b/WebCore/platform/graphics/cairo/GraphicsContextCairo.cpp
@@ -860,10 +860,10 @@ void GraphicsContext::createPlatformShadow(PassOwnPtr<ImageBuffer> buffer, const
     RefPtr<Filter> filter = ImageBufferFilter::create();
     filter->setSourceImage(buffer.release());
     RefPtr<FilterEffect> source = SourceGraphic::create();
-    source->setSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
+    source->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
     source->setIsAlphaImage(true);
     RefPtr<FilterEffect> blur = FEGaussianBlur::create(source.get(), kernelSize, kernelSize);
-    blur->setSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
+    blur->setScaledSubRegion(FloatRect(FloatPoint(), shadowRect.size()));
     blur->apply(filter.get());
 
     // Mask the filter with the shadow color and draw it to the context.
diff --git a/WebCore/platform/graphics/filters/FEBlend.cpp b/WebCore/platform/graphics/filters/FEBlend.cpp
index 2364cc4..f362148 100644
--- a/WebCore/platform/graphics/filters/FEBlend.cpp
+++ b/WebCore/platform/graphics/filters/FEBlend.cpp
@@ -111,10 +111,10 @@ void FEBlend::apply(Filter* filter)
     if (!getEffectContext())
         return;
 
-    IntRect effectADrawingRect = calculateDrawingIntRect(m_in->subRegion());
+    IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
     RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
 
-    IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->subRegion());
+    IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion());
     RefPtr<CanvasPixelArray> srcPixelArrayB(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect)->data());
 
     IntRect imageRect(IntPoint(), resultImage()->size());
diff --git a/WebCore/platform/graphics/filters/FEColorMatrix.cpp b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
index 9d1693a..f422157 100644
--- a/WebCore/platform/graphics/filters/FEColorMatrix.cpp
+++ b/WebCore/platform/graphics/filters/FEColorMatrix.cpp
@@ -164,7 +164,7 @@ void FEColorMatrix::apply(Filter* filter)
     if (!filterContext)
         return;
 
-    filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->subRegion()));
+    filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
 
     IntRect imageRect(IntPoint(), resultImage()->size());
     PassRefPtr<ImageData> imageData(resultImage()->getUnmultipliedImageData(imageRect));
diff --git a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
index 0d76d8d..1d9cfff 100644
--- a/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
+++ b/WebCore/platform/graphics/filters/FEComponentTransfer.cpp
@@ -165,7 +165,7 @@ void FEComponentTransfer::apply(Filter* filter)
     for (unsigned channel = 0; channel < 4; channel++)
         (*callEffect[transferFunction[channel].type])(tables[channel], transferFunction[channel]);
 
-    IntRect drawingRect = calculateDrawingIntRect(m_in->subRegion());
+    IntRect drawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
     RefPtr<ImageData> imageData(m_in->resultImage()->getUnmultipliedImageData(drawingRect));
     CanvasPixelArray* srcPixelArray(imageData->data());
 
diff --git a/WebCore/platform/graphics/filters/FEComposite.cpp b/WebCore/platform/graphics/filters/FEComposite.cpp
index cd858ee..c540cb7 100644
--- a/WebCore/platform/graphics/filters/FEComposite.cpp
+++ b/WebCore/platform/graphics/filters/FEComposite.cpp
@@ -133,32 +133,32 @@ void FEComposite::apply(Filter* filter)
     FloatRect srcRect = FloatRect(0.f, 0.f, -1.f, -1.f);
     switch (m_type) {
     case FECOMPOSITE_OPERATOR_OVER:
-        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->subRegion()));
-        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->subRegion()));
+        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
+        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
         break;
     case FECOMPOSITE_OPERATOR_IN:
         filterContext->save();
-        filterContext->clipToImageBuffer(calculateDrawingRect(m_in2->subRegion()), m_in2->resultImage());
-        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->subRegion()));
+        filterContext->clipToImageBuffer(calculateDrawingRect(m_in2->scaledSubRegion()), m_in2->resultImage());
+        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
         filterContext->restore();
         break;
     case FECOMPOSITE_OPERATOR_OUT:
-        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->subRegion()));
-        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->subRegion()), srcRect, CompositeDestinationOut);
+        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()));
+        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()), srcRect, CompositeDestinationOut);
         break;
     case FECOMPOSITE_OPERATOR_ATOP:
-        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->subRegion()));
-        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->subRegion()), srcRect, CompositeSourceAtop);
+        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
+        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeSourceAtop);
         break;
     case FECOMPOSITE_OPERATOR_XOR:
-        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->subRegion()));
-        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->subRegion()), srcRect, CompositeXOR);
+        filterContext->drawImage(m_in2->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in2->scaledSubRegion()));
+        filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, calculateDrawingRect(m_in->scaledSubRegion()), srcRect, CompositeXOR);
         break;
     case FECOMPOSITE_OPERATOR_ARITHMETIC: {
-        IntRect effectADrawingRect = calculateDrawingIntRect(m_in->subRegion());
+        IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
         RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
 
-        IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->subRegion());
+        IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion());
         RefPtr<ImageData> imageData(m_in2->resultImage()->getPremultipliedImageData(effectBDrawingRect));
         CanvasPixelArray* srcPixelArrayB(imageData->data());
 
diff --git a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
index f480f10..0b97e39 100644
--- a/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
+++ b/WebCore/platform/graphics/filters/FEGaussianBlur.cpp
@@ -32,6 +32,8 @@
 #include <math.h>
 #include <wtf/MathExtras.h>
 
+using std::max;
+
 namespace WebCore {
 
 FEGaussianBlur::FEGaussianBlur(FilterEffect* in, const float& x, const float& y)
@@ -111,10 +113,12 @@ void FEGaussianBlur::apply(Filter* filter)
     if (m_x == 0 || m_y == 0)
         return;
 
-    unsigned sdx = static_cast<unsigned>(floor(m_x * 3 * sqrt(2 * piDouble) / 4.f + 0.5f));
-    unsigned sdy = static_cast<unsigned>(floor(m_y * 3 * sqrt(2 * piDouble) / 4.f + 0.5f));
+    unsigned sdx = static_cast<unsigned>(floor(m_x * filter->filterResolution().width() * 3 * sqrt(2 * piDouble) / 4.f + 0.5f));
+    unsigned sdy = static_cast<unsigned>(floor(m_y * filter->filterResolution().height() * 3 * sqrt(2 * piDouble) / 4.f + 0.5f));
+    sdx = max(sdx, static_cast<unsigned>(1));
+    sdy = max(sdy, static_cast<unsigned>(1));
 
-    IntRect effectDrawingRect = calculateDrawingIntRect(m_in->subRegion());
+    IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
     RefPtr<ImageData> srcImageData(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect));
     CanvasPixelArray* srcPixelArray(srcImageData->data());
 
diff --git a/WebCore/platform/graphics/filters/Filter.h b/WebCore/platform/graphics/filters/Filter.h
index 0728e84..8924b94 100644
--- a/WebCore/platform/graphics/filters/Filter.h
+++ b/WebCore/platform/graphics/filters/Filter.h
@@ -22,6 +22,7 @@
 
 #if ENABLE(FILTERS)
 #include "FloatRect.h"
+#include "FloatSize.h"
 #include "ImageBuffer.h"
 #include "StringHash.h"
 
@@ -40,15 +41,21 @@ namespace WebCore {
         void setSourceImage(PassOwnPtr<ImageBuffer> sourceImage) { m_sourceImage = sourceImage; }
         ImageBuffer* sourceImage() { return m_sourceImage.get(); }
 
+        FloatSize filterResolution() const { return m_filterResolution; }
+        void setFilterResolution(const FloatSize& filterResolution) { m_filterResolution = filterResolution; }
+
         virtual FloatRect sourceImageRect() const = 0;
         virtual FloatRect filterRegion() const = 0;
 
         // SVG specific
-        virtual void calculateEffectSubRegion(FilterEffect*) const = 0;
+        virtual void calculateEffectSubRegion(FilterEffect*) { }
+
+        virtual FloatSize maxImageSize() const = 0;
         virtual bool effectBoundingBoxMode() const = 0;
 
     private:
         OwnPtr<ImageBuffer> m_sourceImage;
+        FloatSize m_filterResolution;
     };
 
 } // namespace WebCore
diff --git a/WebCore/platform/graphics/filters/FilterEffect.cpp b/WebCore/platform/graphics/filters/FilterEffect.cpp
index 68900b5..5583813 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.cpp
+++ b/WebCore/platform/graphics/filters/FilterEffect.cpp
@@ -58,21 +58,21 @@ FloatRect FilterEffect::calculateEffectRect(Filter* filter)
 
 IntRect FilterEffect::calculateDrawingIntRect(const FloatRect& effectRect)
 {
-    IntPoint location = roundedIntPoint(FloatPoint(subRegion().x() - effectRect.x(),
-                                                   subRegion().y() - effectRect.y()));
+    IntPoint location = roundedIntPoint(FloatPoint(scaledSubRegion().x() - effectRect.x(),
+                                                   scaledSubRegion().y() - effectRect.y()));
     return IntRect(location, resultImage()->size());
 }
 
 FloatRect FilterEffect::calculateDrawingRect(const FloatRect& srcRect)
 {
-    FloatPoint startPoint = FloatPoint(srcRect.x() - subRegion().x(), srcRect.y() - subRegion().y());
+    FloatPoint startPoint = FloatPoint(srcRect.x() - scaledSubRegion().x(), srcRect.y() - scaledSubRegion().y());
     FloatRect drawingRect = FloatRect(startPoint, srcRect.size());
     return drawingRect;
 }
 
 GraphicsContext* FilterEffect::getEffectContext()
 {
-    IntRect bufferRect = enclosingIntRect(subRegion());
+    IntRect bufferRect = enclosingIntRect(scaledSubRegion());
     m_effectBuffer = ImageBuffer::create(bufferRect.size(), LinearRGB);
     return m_effectBuffer->context();
 }
diff --git a/WebCore/platform/graphics/filters/FilterEffect.h b/WebCore/platform/graphics/filters/FilterEffect.h
index b30e513..a46d795 100644
--- a/WebCore/platform/graphics/filters/FilterEffect.h
+++ b/WebCore/platform/graphics/filters/FilterEffect.h
@@ -44,6 +44,12 @@ namespace WebCore {
         FloatRect subRegion() const { return m_subRegion; }
         void setSubRegion(const FloatRect& subRegion) { m_subRegion = subRegion; }
 
+        FloatRect scaledSubRegion() const { return m_scaledSubRegion; }
+        void setScaledSubRegion(const FloatRect& scaledSubRegion) { m_scaledSubRegion = scaledSubRegion; }
+
+        FloatRect effectBoundaries() const { return m_effectBoundaries; }
+        void setEffectBoundaries(const FloatRect& effectBoundaries) { m_effectBoundaries = effectBoundaries; }
+
         bool hasX() { return m_hasX; }
         void setHasX(bool value) { m_hasX = value; }
 
@@ -96,7 +102,9 @@ namespace WebCore {
 
         bool m_alphaImage;
 
+        FloatRect m_effectBoundaries;
         FloatRect m_subRegion;
+        FloatRect m_scaledSubRegion;
         FloatRect m_unionOfChildEffectSubregions;
 
         mutable OwnPtr<ImageBuffer> m_effectBuffer;
diff --git a/WebCore/platform/graphics/filters/ImageBufferFilter.cpp b/WebCore/platform/graphics/filters/ImageBufferFilter.cpp
index ddb3af8..33953d6 100644
--- a/WebCore/platform/graphics/filters/ImageBufferFilter.cpp
+++ b/WebCore/platform/graphics/filters/ImageBufferFilter.cpp
@@ -23,11 +23,14 @@
 #if ENABLE(FILTERS)
 #include "ImageBufferFilter.h"
 
+#include "FloatSize.h"
+
 namespace WebCore {
 
 ImageBufferFilter::ImageBufferFilter()
     : Filter()
 {
+    setFilterResolution(FloatSize(1.f, 1.f));
 }
 
 PassRefPtr<ImageBufferFilter> ImageBufferFilter::create()
diff --git a/WebCore/platform/graphics/filters/ImageBufferFilter.h b/WebCore/platform/graphics/filters/ImageBufferFilter.h
index ef972d9..a2775ea 100644
--- a/WebCore/platform/graphics/filters/ImageBufferFilter.h
+++ b/WebCore/platform/graphics/filters/ImageBufferFilter.h
@@ -25,6 +25,7 @@
 #include "Filter.h"
 #include "FilterEffect.h"
 #include "FloatRect.h"
+#include "FloatSize.h"
 
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -41,7 +42,9 @@ public:
 
     // SVG specific
     virtual bool effectBoundingBoxMode() const { return false; }
-    virtual void calculateEffectSubRegion(FilterEffect*) const { }
+
+    virtual FloatSize maxImageSize() const { return FloatSize(); }
+    virtual void calculateEffectSubRegion(FilterEffect*) { }
 
 private:
     ImageBufferFilter();
diff --git a/WebCore/platform/graphics/filters/SourceAlpha.cpp b/WebCore/platform/graphics/filters/SourceAlpha.cpp
index 65051a5..539bb44 100644
--- a/WebCore/platform/graphics/filters/SourceAlpha.cpp
+++ b/WebCore/platform/graphics/filters/SourceAlpha.cpp
@@ -50,6 +50,8 @@ FloatRect SourceAlpha::calculateEffectRect(Filter* filter)
     if (filter->sourceImageRect().y() < filter->filterRegion().y())
         clippedSourceRect.setY(filter->filterRegion().y());
     setSubRegion(clippedSourceRect);
+    clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
+    setScaledSubRegion(clippedSourceRect);
     return filter->filterRegion();
 }
 
diff --git a/WebCore/platform/graphics/filters/SourceGraphic.cpp b/WebCore/platform/graphics/filters/SourceGraphic.cpp
index 835b359..cc55618 100644
--- a/WebCore/platform/graphics/filters/SourceGraphic.cpp
+++ b/WebCore/platform/graphics/filters/SourceGraphic.cpp
@@ -49,6 +49,8 @@ FloatRect SourceGraphic::calculateEffectRect(Filter* filter)
     if (filter->sourceImageRect().y() < filter->filterRegion().y())
         clippedSourceRect.setY(filter->filterRegion().y());
     setSubRegion(clippedSourceRect);
+    clippedSourceRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
+    setScaledSubRegion(clippedSourceRect);
     return filter->filterRegion();
 }
 
diff --git a/WebCore/svg/SVGFilterElement.cpp b/WebCore/svg/SVGFilterElement.cpp
index a5c8c8d..bb14448 100644
--- a/WebCore/svg/SVGFilterElement.cpp
+++ b/WebCore/svg/SVGFilterElement.cpp
@@ -26,12 +26,14 @@
 #include "SVGFilterElement.h"
 
 #include "Attr.h"
-#include "SVGFilterBuilder.h"
+#include "FloatSize.h"
 #include "MappedAttribute.h"
 #include "PlatformString.h"
+#include "SVGFilterBuilder.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 #include "SVGLength.h"
 #include "SVGNames.h"
+#include "SVGParserUtilities.h"
 #include "SVGResourceFilter.h"
 #include "SVGUnitTypes.h"
 
@@ -89,7 +91,13 @@ void SVGFilterElement::parseMappedAttribute(MappedAttribute* attr)
         setWidthBaseValue(SVGLength(LengthModeWidth, value));
     else if (attr->name() == SVGNames::heightAttr)
         setHeightBaseValue(SVGLength(LengthModeHeight, value));
-    else {
+    else if (attr->name() == SVGNames::filterResAttr) {
+        float x, y;
+        if (parseNumberOptionalNumber(value, x, y)) {
+            setFilterResXBaseValue(x);
+            setFilterResYBaseValue(y);
+        }
+    } else {
         if (SVGURIReference::parseMappedAttribute(attr))
             return;
         if (SVGLangSpace::parseMappedAttribute(attr))
@@ -130,6 +138,11 @@ void SVGFilterElement::buildFilter(const FloatRect& targetRect) const
     m_filter->setEffectBoundingBoxMode(primitiveBBoxMode);
     m_filter->setFilterBoundingBoxMode(filterBBoxMode);
 
+    if (hasAttribute(SVGNames::filterResAttr)) {
+        m_filter->setHasFilterResolution(true);
+        m_filter->setFilterResolution(FloatSize(filterResX(), filterResY()));
+    }
+
     // Add effects to the filter
     m_filter->builder()->clearEffects();
     for (Node* n = firstChild(); n != 0; n = n->nextSibling()) {
diff --git a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
index 67c8bff..08559b4 100644
--- a/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
+++ b/WebCore/svg/SVGFilterPrimitiveStandardAttributes.cpp
@@ -97,7 +97,7 @@ void SVGFilterPrimitiveStandardAttributes::setStandardAttributes(SVGResourceFilt
                                width().value(this),
                                height().value(this));
 
-    filterEffect->setSubRegion(effectBBox);
+    filterEffect->setEffectBoundaries(effectBBox);
 }
 
 }
diff --git a/WebCore/svg/graphics/SVGResourceFilter.cpp b/WebCore/svg/graphics/SVGResourceFilter.cpp
index 7482f5e..fcf0e40 100644
--- a/WebCore/svg/graphics/SVGResourceFilter.cpp
+++ b/WebCore/svg/graphics/SVGResourceFilter.cpp
@@ -35,6 +35,10 @@
 #include "SVGRenderTreeAsText.h"
 #include "SVGFilterPrimitiveStandardAttributes.h"
 
+static const float kMaxFilterSize = 5000.0f;
+
+using std::min;
+
 namespace WebCore {
 
 SVGResourceFilter::SVGResourceFilter(const SVGFilterElement* ownerElement)
@@ -42,6 +46,9 @@ SVGResourceFilter::SVGResourceFilter(const SVGFilterElement* ownerElement)
     , m_ownerElement(ownerElement)
     , m_filterBBoxMode(false)
     , m_effectBBoxMode(false)
+    , m_filterRes(false)
+    , m_scaleX(1.f)
+    , m_scaleY(1.f)
     , m_savedContext(0)
     , m_sourceGraphicBuffer(0)
 {
@@ -52,27 +59,72 @@ SVGResourceFilter::~SVGResourceFilter()
 {
 }
 
+static inline bool shouldProcessFilter(SVGResourceFilter* filter)
+{
+    return (!filter->scaleX() || !filter->scaleY() || !filter->filterBoundingBox().width()
+            || !filter->filterBoundingBox().height());
+}
+
 void SVGResourceFilter::addFilterEffect(SVGFilterPrimitiveStandardAttributes* effectAttributes, PassRefPtr<FilterEffect> effect)
 {
     effectAttributes->setStandardAttributes(this, effect.get());
     builder()->add(effectAttributes->result(), effect);
 }
 
+bool SVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size)
+{
+    bool matchesFilterSize = true;
+    if (size.width() > kMaxFilterSize) {
+        m_scaleX *= kMaxFilterSize / size.width();
+        matchesFilterSize = false;
+    }
+    if (size.height() > kMaxFilterSize) {
+        m_scaleY *= kMaxFilterSize / size.height();
+        matchesFilterSize = false;
+    }
+
+    return matchesFilterSize;
+}
+
 void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObject* object)
 {
     FloatRect targetRect = object->objectBoundingBox();
     m_ownerElement->buildFilter(targetRect);
 
+    if (shouldProcessFilter(this))
+        return;
+
     // clip sourceImage to filterRegion
     FloatRect clippedSourceRect = targetRect;
     clippedSourceRect.intersect(m_filterBBox);
 
+    // scale filter size to filterRes
+    FloatRect tempSourceRect = clippedSourceRect;
+    if (m_filterRes) {
+        m_scaleX = m_filterResSize.width() / m_filterBBox.width();
+        m_scaleY = m_filterResSize.height() / m_filterBBox.height();
+    }
+
+    // scale to big sourceImage size to kMaxFilterSize
+    tempSourceRect.scale(m_scaleX, m_scaleY);
+    fitsInMaximumImageSize(tempSourceRect.size());
+
     // prepare Filters
     m_filter = SVGFilter::create(targetRect, m_filterBBox, m_effectBBoxMode);
+    m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY));
 
     FilterEffect* lastEffect = m_filterBuilder->lastEffect();
-    if (lastEffect)
+    if (lastEffect) {
         lastEffect->calculateEffectRect(m_filter.get());
+        // at least one FilterEffect has a too big image size,
+        // recalculate the effect sizes with new scale factors
+        if (!fitsInMaximumImageSize(m_filter->maxImageSize())) {
+            m_filter->setFilterResolution(FloatSize(m_scaleX, m_scaleY));
+            lastEffect->calculateEffectRect(m_filter.get());
+        }
+    }
+
+    clippedSourceRect.scale(m_scaleX, m_scaleY);
 
     // Draw the content of the current element and it's childs to a imageBuffer to get the SourceGraphic.
     // The size of the SourceGraphic is clipped to the size of the filterRegion.
@@ -83,6 +135,7 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj
         return;
 
     GraphicsContext* sourceGraphicContext = sourceGraphic->context();
+    sourceGraphicContext->scale(FloatSize(m_scaleX, m_scaleY));
     sourceGraphicContext->translate(-targetRect.x(), -targetRect.y());
     sourceGraphicContext->clearRect(FloatRect(FloatPoint(), targetRect.size()));
     m_sourceGraphicBuffer.set(sourceGraphic.release());
@@ -93,6 +146,9 @@ void SVGResourceFilter::prepareFilter(GraphicsContext*& context, const RenderObj
 
 void SVGResourceFilter::applyFilter(GraphicsContext*& context, const RenderObject* object)
 {
+    if (shouldProcessFilter(this))
+        return;
+
     if (!m_savedContext)
         return;
 
diff --git a/WebCore/svg/graphics/SVGResourceFilter.h b/WebCore/svg/graphics/SVGResourceFilter.h
index 86b11fe..ffd926d 100644
--- a/WebCore/svg/graphics/SVGResourceFilter.h
+++ b/WebCore/svg/graphics/SVGResourceFilter.h
@@ -53,6 +53,9 @@ public:
     
     virtual SVGResourceType resourceType() const { return FilterResourceType; }
 
+    void setFilterResolution(const FloatSize& filterResSize) { m_filterResSize = filterResSize; }
+    void setHasFilterResolution(bool filterRes) { m_filterRes = filterRes; }
+
     bool filterBoundingBoxMode() const { return m_filterBBoxMode; }
     void setFilterBoundingBoxMode(bool bboxMode) { m_filterBBoxMode = bboxMode; }
 
@@ -62,12 +65,17 @@ public:
     FloatRect filterRect() const { return m_filterRect; }
     void setFilterRect(const FloatRect& rect) { m_filterRect = rect; }
 
+    float scaleX() const { return m_scaleX; }
+    float scaleY() const { return m_scaleY; }
+
     FloatRect filterBoundingBox() { return m_filterBBox; }
     void setFilterBoundingBox(const FloatRect& rect) { m_filterBBox = rect; }
 
     void prepareFilter(GraphicsContext*&, const RenderObject*);
     void applyFilter(GraphicsContext*&, const RenderObject*);
 
+    bool fitsInMaximumImageSize(const FloatSize&);
+
     void addFilterEffect(SVGFilterPrimitiveStandardAttributes*, PassRefPtr<FilterEffect>);
 
     SVGFilterBuilder* builder() { return m_filterBuilder.get(); }
@@ -81,9 +89,13 @@ private:
 
     bool m_filterBBoxMode : 1;
     bool m_effectBBoxMode : 1;
+    bool m_filterRes : 1;
+    float m_scaleX;
+    float m_scaleY;
 
     FloatRect m_filterRect;
     FloatRect m_filterBBox;
+    FloatSize m_filterResSize;
 
     OwnPtr<SVGFilterBuilder> m_filterBuilder;
     GraphicsContext* m_savedContext;
diff --git a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp
index cc5a4b3..a22bc94 100644
--- a/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEDisplacementMap.cpp
@@ -93,10 +93,10 @@ void FEDisplacementMap::apply(Filter* filter)
     if (!getEffectContext())
         return;
 
-    IntRect effectADrawingRect = calculateDrawingIntRect(m_in->subRegion());
+    IntRect effectADrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
     RefPtr<CanvasPixelArray> srcPixelArrayA(m_in->resultImage()->getPremultipliedImageData(effectADrawingRect)->data());
 
-    IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->subRegion());
+    IntRect effectBDrawingRect = calculateDrawingIntRect(m_in2->scaledSubRegion());
     RefPtr<CanvasPixelArray> srcPixelArrayB(m_in2->resultImage()->getUnmultipliedImageData(effectBDrawingRect)->data());
 
     IntRect imageRect(IntPoint(), resultImage()->size());
@@ -104,15 +104,17 @@ void FEDisplacementMap::apply(Filter* filter)
 
     ASSERT(srcPixelArrayA->length() == srcPixelArrayB->length());
 
-    float scale = m_scale / 255.f;
-    float scaleAdjustment = 0.5f - 0.5f * m_scale;
+    float scaleX = m_scale / 255.f * filter->filterResolution().width();
+    float scaleY = m_scale / 255.f * filter->filterResolution().height();
+    float scaleAdjustmentX = (0.5f - 0.5f * m_scale) * filter->filterResolution().width();
+    float scaleAdjustmentY = (0.5f - 0.5f * m_scale) * filter->filterResolution().height();
     int stride = imageRect.width() * 4;
     for (int y = 0; y < imageRect.height(); ++y) {
         int line = y * stride;
         for (int x = 0; x < imageRect.width(); ++x) {
             int dstIndex = line + x * 4;
-            int srcX = x + static_cast<int>(scale * srcPixelArrayB->get(dstIndex + m_xChannelSelector - 1) + scaleAdjustment);
-            int srcY = y + static_cast<int>(scale * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustment);
+            int srcX = x + static_cast<int>(scaleX * srcPixelArrayB->get(dstIndex + m_xChannelSelector - 1) + scaleAdjustmentX);
+            int srcY = y + static_cast<int>(scaleY * srcPixelArrayB->get(dstIndex + m_yChannelSelector - 1) + scaleAdjustmentY);
             for (unsigned channel = 0; channel < 4; ++channel) {
                 if (srcX < 0 || srcX >= imageRect.width() || srcY < 0 || srcY >= imageRect.height())
                     imageData->data()->set(dstIndex + channel, static_cast<unsigned char>(0));
diff --git a/WebCore/svg/graphics/filters/SVGFEFlood.cpp b/WebCore/svg/graphics/filters/SVGFEFlood.cpp
index 22be90f..648bf54 100644
--- a/WebCore/svg/graphics/filters/SVGFEFlood.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEFlood.cpp
@@ -70,7 +70,7 @@ void FEFlood::apply(Filter*)
         return;
 
     Color color = colorWithOverrideAlpha(floodColor().rgb(), floodOpacity());
-    filterContext->fillRect(FloatRect(FloatPoint(), subRegion().size()), color, DeviceColorSpace);
+    filterContext->fillRect(FloatRect(FloatPoint(), scaledSubRegion().size()), color, DeviceColorSpace);
 }
 
 void FEFlood::dump()
diff --git a/WebCore/svg/graphics/filters/SVGFEMerge.cpp b/WebCore/svg/graphics/filters/SVGFEMerge.cpp
index 5ceea87..3f9ad38 100644
--- a/WebCore/svg/graphics/filters/SVGFEMerge.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEMerge.cpp
@@ -78,7 +78,7 @@ void FEMerge::apply(Filter* filter)
         return;
 
     for (unsigned i = 0; i < m_mergeInputs.size(); i++) {
-        FloatRect destRect = calculateDrawingRect(m_mergeInputs[i]->subRegion());
+        FloatRect destRect = calculateDrawingRect(m_mergeInputs[i]->scaledSubRegion());
         filterContext->drawImage(m_mergeInputs[i]->resultImage()->image(), DeviceColorSpace, destRect);
     }
 }
diff --git a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp
index 290cc7c..20d109a 100644
--- a/WebCore/svg/graphics/filters/SVGFEMorphology.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEMorphology.cpp
@@ -94,12 +94,12 @@ void FEMorphology::apply(Filter* filter)
         return;
 
     IntRect imageRect(IntPoint(), resultImage()->size());
-    IntRect effectDrawingRect = calculateDrawingIntRect(m_in->subRegion());
+    IntRect effectDrawingRect = calculateDrawingIntRect(m_in->scaledSubRegion());
     RefPtr<CanvasPixelArray> srcPixelArray(m_in->resultImage()->getPremultipliedImageData(effectDrawingRect)->data());
     RefPtr<ImageData> imageData = ImageData::create(imageRect.width(), imageRect.height());
 
-    int radiusX = static_cast<int>(m_radiusX);
-    int radiusY = static_cast<int>(m_radiusY);
+    int radiusX = static_cast<int>(m_radiusX * filter->filterResolution().width());
+    int radiusY = static_cast<int>(m_radiusY * filter->filterResolution().height());
     int effectWidth = effectDrawingRect.width() * 4;
     
     // Limit the radius size to effect width
diff --git a/WebCore/svg/graphics/filters/SVGFEOffset.cpp b/WebCore/svg/graphics/filters/SVGFEOffset.cpp
index 1c820ca..9fd50ed 100644
--- a/WebCore/svg/graphics/filters/SVGFEOffset.cpp
+++ b/WebCore/svg/graphics/filters/SVGFEOffset.cpp
@@ -74,15 +74,20 @@ void FEOffset::apply(Filter* filter)
     if (!filterContext)
         return;
 
+    FloatRect sourceImageRect = filter->sourceImageRect();
+    sourceImageRect.scale(filter->filterResolution().width(), filter->filterResolution().height());
+
     if (filter->effectBoundingBoxMode()) {
-        setDx(dx() * filter->sourceImageRect().width());
-        setDy(dy() * filter->sourceImageRect().height());
+        m_dx *= sourceImageRect.width();
+        m_dy *= sourceImageRect.height();
     }
+    m_dx *= filter->filterResolution().width();
+    m_dy *= filter->filterResolution().height();
 
-    FloatRect dstRect = FloatRect(dx() + m_in->subRegion().x() - subRegion().x(),
-                                  dy() + m_in->subRegion().y() - subRegion().y(),
-                                  m_in->subRegion().width(),
-                                  m_in->subRegion().height());
+    FloatRect dstRect = FloatRect(m_dx + m_in->scaledSubRegion().x() - scaledSubRegion().x(),
+                                  m_dy + m_in->scaledSubRegion().y() - scaledSubRegion().y(),
+                                  m_in->scaledSubRegion().width(),
+                                  m_in->scaledSubRegion().height());
 
     filterContext->drawImage(m_in->resultImage()->image(), DeviceColorSpace, dstRect);
 }
diff --git a/WebCore/svg/graphics/filters/SVGFETile.cpp b/WebCore/svg/graphics/filters/SVGFETile.cpp
index e37ef23..e97f68f 100644
--- a/WebCore/svg/graphics/filters/SVGFETile.cpp
+++ b/WebCore/svg/graphics/filters/SVGFETile.cpp
@@ -58,12 +58,15 @@ void FETile::apply(Filter* filter)
     if (!filterContext)
         return;
 
-    IntRect tileRect = enclosingIntRect(m_in->subRegion());
+    IntRect tileRect = enclosingIntRect(m_in->scaledSubRegion());
 
     // Source input needs more attention. It has the size of the filterRegion but gives the
     // size of the cutted sourceImage back. This is part of the specification and optimization.
-    if (m_in->isSourceInput())
-        tileRect = enclosingIntRect(filter->filterRegion());
+    if (m_in->isSourceInput()) {
+        FloatRect filterRegion = filter->filterRegion();
+        filterRegion.scale(filter->filterResolution().width(), filter->filterResolution().height());
+        tileRect = enclosingIntRect(filterRegion);
+    }
 
     OwnPtr<ImageBuffer> tileImage = ImageBuffer::create(tileRect.size());
     GraphicsContext* tileImageContext = tileImage->context();
@@ -71,11 +74,11 @@ void FETile::apply(Filter* filter)
     RefPtr<Pattern> pattern = Pattern::create(tileImage->image(), true, true);
 
     TransformationMatrix matrix;
-    matrix.translate(m_in->subRegion().x() - subRegion().x(), m_in->subRegion().y() - subRegion().y());
+    matrix.translate(m_in->scaledSubRegion().x() - scaledSubRegion().x(), m_in->scaledSubRegion().y() - scaledSubRegion().y());
     pattern.get()->setPatternSpaceTransform(matrix);
 
     filterContext->setFillPattern(pattern);
-    filterContext->fillRect(FloatRect(FloatPoint(), subRegion().size()));
+    filterContext->fillRect(FloatRect(FloatPoint(), scaledSubRegion().size()));
 }
 
 void FETile::dump()
diff --git a/WebCore/svg/graphics/filters/SVGFilter.cpp b/WebCore/svg/graphics/filters/SVGFilter.cpp
index e684135..4ec4e6e 100644
--- a/WebCore/svg/graphics/filters/SVGFilter.cpp
+++ b/WebCore/svg/graphics/filters/SVGFilter.cpp
@@ -32,9 +32,9 @@ SVGFilter::SVGFilter(const FloatRect& itemBox, const FloatRect& filterRect, bool
 {
 }
 
-void SVGFilter::calculateEffectSubRegion(FilterEffect* effect) const
+void SVGFilter::calculateEffectSubRegion(FilterEffect* effect)
 {
-    FloatRect subRegionBBox = effect->subRegion();
+    FloatRect subRegionBBox = effect->effectBoundaries();
     FloatRect useBBox = effect->unionOfChildEffectSubregions();
     FloatRect newSubRegion = subRegionBBox;
 
@@ -70,6 +70,9 @@ void SVGFilter::calculateEffectSubRegion(FilterEffect* effect) const
     newSubRegion.intersect(m_filterRect);
 
     effect->setSubRegion(newSubRegion);
+    newSubRegion.scale(filterResolution().width(), filterResolution().height());
+    effect->setScaledSubRegion(newSubRegion);
+    m_maxImageSize = m_maxImageSize.expandedTo(newSubRegion.size()); 
 }
 
 PassRefPtr<SVGFilter> SVGFilter::create(const FloatRect& itemBox, const FloatRect& filterRect, bool effectBBoxMode)
diff --git a/WebCore/svg/graphics/filters/SVGFilter.h b/WebCore/svg/graphics/filters/SVGFilter.h
index a5da050..c4714c6 100644
--- a/WebCore/svg/graphics/filters/SVGFilter.h
+++ b/WebCore/svg/graphics/filters/SVGFilter.h
@@ -24,6 +24,7 @@
 #include "Filter.h"
 #include "FilterEffect.h"
 #include "FloatRect.h"
+#include "FloatSize.h"
 
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -35,15 +36,18 @@ namespace WebCore {
     public:
         static PassRefPtr<SVGFilter> create(const FloatRect&, const FloatRect&, bool);
 
-        bool effectBoundingBoxMode() const { return m_effectBBoxMode; }
+        virtual bool effectBoundingBoxMode() const { return m_effectBBoxMode; }
 
-        FloatRect filterRegion() const { return m_filterRect; }
-        FloatRect sourceImageRect() const { return m_itemBox; }
-        void calculateEffectSubRegion(FilterEffect*) const;
+        virtual FloatRect filterRegion() const { return m_filterRect; }
+        virtual FloatRect sourceImageRect() const { return m_itemBox; }
+
+        virtual FloatSize maxImageSize() const { return m_maxImageSize; }
+        virtual void calculateEffectSubRegion(FilterEffect*);
 
     private:
         SVGFilter(const FloatRect& itemBox, const FloatRect& filterRect, bool effectBBoxMode);
 
+        FloatSize m_maxImageSize;
         FloatRect m_itemBox;
         FloatRect m_filterRect;
         bool m_effectBBoxMode;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list