Applying a filter on an SVG element, which is larger than 4096 pixels, causes this...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 May 2015 22:46:43 +0000 (22:46 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 May 2015 22:46:43 +0000 (22:46 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144335

Patch by Said Abou-Hallawa <sabouhallawa@apple.com> on 2015-05-07
Reviewed by Darin Adler.

Source/WebCore:

When the SVG element is larger than 4096x4096 pixels and it has a filter,
a clipper or a masker, the ImageBuffer which is created for drawing the
sourceGraphicBuffer has to be clamped to this size. The reason for this
clamping is the FilterEffect simply ignores processing any ImageBuffer
larger than this size.

The bug was happening because we did not propagate the clamping logic to
the FilterEffect. The FilterEffect result ImageBuffer was not clamped as
what we do for drawing the sourceGraphicBuffer. If only the destination
point is specified, the GraphicsContext::drawImageBuffer() assumes the
source and the destination images have the same size which is not true
with the clamping.

The fix is to add the clamping logic to the FilterEffect. Two places we
need to change. (1) FilterEffect::createImageBufferResult() has to apply
the same clamping we do in SVGRenderingContext::createImageBuffer(). (2)
FilterEffect::drawingRegionOfInputImage() has to consider the clamping
when mapping from absolute coordinates to the ImageBuffer coordinates.

Tests: svg/filters/big-sized-off-viewport-filter.svg

* platform/graphics/ImageBuffer.cpp:
(WebCore::ImageBuffer::isSizeClamped):
(WebCore::ImageBuffer::clampedSize):
(WebCore::ImageBuffer::clampedRect):
* platform/graphics/ImageBuffer.h:
(WebCore::ImageBuffer::setSpaceSize): Move all the clamping helper methods
from SVGRenderingContext and RenderSVGResourceFilter to the ImageBuffer.

* platform/graphics/filters/FEColorMatrix.cpp:
(WebCore::FEColorMatrix::platformApplySoftware): Use logicalSize() of the
result image instead of using absolutePaintRect(). The later returns the
rectangle of the element without clamping.

* platform/graphics/filters/FETile.cpp:
(WebCore::FETile::platformApplySoftware):
* rendering/svg/RenderSVGResourceClipper.cpp:
(WebCore::RenderSVGResourceClipper::applyClippingToContext):
* rendering/svg/RenderSVGResourceFilter.cpp:
(WebCore::RenderSVGResourceFilter::applyResource):
(WebCore::RenderSVGResourceFilter::fitsInMaximumImageSize): Deleted.
* rendering/svg/RenderSVGResourceFilter.h:
* rendering/svg/RenderSVGResourceGradient.cpp:
(WebCore::createMaskAndSwapContextForTextGradient):
(WebCore::clipToTextMask):
* rendering/svg/RenderSVGResourceMasker.cpp:
(WebCore::RenderSVGResourceMasker::applySVGMask):
* rendering/svg/RenderSVGResourcePattern.cpp:
(WebCore::RenderSVGResourcePattern::buildPattern):
(WebCore::RenderSVGResourcePattern::createTileImage): Make the modifications
which are needed because of moving the clamping helper methods to ImageBuffer
and because of changing the prototype of SVGRenderingContext methods.

* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::drawingRegionOfInputImage): Consider the clamping
when mapping from absolute coordinates to the ImageBuffer coordinates.

(WebCore::FilterEffect::createImageBufferResult): Apply the same clamping
we do in SVGRenderingContext::createImageBuffer() when creating the
FilterEffect result ImageBuffer.

(WebCore::FilterEffect::apply):
(WebCore::FilterEffect::asUnmultipliedImage):
(WebCore::FilterEffect::asPremultipliedImage):
(WebCore::FilterEffect::copyUnmultipliedImage):
(WebCore::FilterEffect::copyPremultipliedImage):
(WebCore::FilterEffect::createUnmultipliedImageResult):
(WebCore::FilterEffect::createPremultipliedImageResult):
(WebCore::FilterEffect::maxFilterArea): Deleted.
(WebCore::FilterEffect::isFilterSizeValid): Deleted.
* platform/graphics/filters/FilterEffect.h: Use the new ImageBuffer clamping
helper methods and delete the local ones.

* platform/graphics/transforms/AffineTransform.cpp:
(WebCore::AffineTransform::scaleNonUniform):
(WebCore::AffineTransform::scale):
(WebCore::AffineTransform::translate):
* platform/graphics/transforms/AffineTransform.h: Add new scale and translate
overloads to AffineTransform.

* rendering/FilterEffectRenderer.cpp:
(WebCore::FilterEffectRenderer::updateBackingStoreRect):
(WebCore::FilterEffectRendererHelper::beginFilterEffect): Code clean up.

* rendering/svg/SVGRenderingContext.cpp:
(WebCore::SVGRenderingContext::calculateScreenFontSizeScalingFactor):
(WebCore::SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem):
Return the AffineTransform instead of passing it through the reference of
an argument.

(WebCore::SVGRenderingContext::createImageBuffer):
(WebCore::SVGRenderingContext::createImageBufferForPattern): Deleted.
Code clean up and method rename.

(WebCore::SVGRenderingContext::clampedAbsoluteTargetRect): Deleted.
(WebCore::SVGRenderingContext::clampedAbsoluteSize): Deleted.
* rendering/svg/SVGRenderingContext.h: Move the clamping helper methods to
the ImageBuffer class.

LayoutTests:

* svg/filters/big-sized-off-viewport-filter-expected.svg: Added.
* svg/filters/big-sized-off-viewport-filter.svg: Added.
Ensure when applying a filter on a large SVG element, the viewport of the
SVG includes the correct drawing part of this element.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183956 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/filters/big-sized-off-viewport-filter-expected.svg [new file with mode: 0644]
LayoutTests/svg/filters/big-sized-off-viewport-filter.svg [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/ImageBuffer.cpp
Source/WebCore/platform/graphics/ImageBuffer.h
Source/WebCore/platform/graphics/filters/FEColorMatrix.cpp
Source/WebCore/platform/graphics/filters/FETile.cpp
Source/WebCore/platform/graphics/filters/FilterEffect.cpp
Source/WebCore/platform/graphics/filters/FilterEffect.h
Source/WebCore/platform/graphics/transforms/AffineTransform.cpp
Source/WebCore/platform/graphics/transforms/AffineTransform.h
Source/WebCore/rendering/FilterEffectRenderer.cpp
Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
Source/WebCore/rendering/svg/SVGRenderingContext.cpp
Source/WebCore/rendering/svg/SVGRenderingContext.h

index 8b0c20a..7d73c34 100644 (file)
@@ -1,3 +1,15 @@
+2015-05-07  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Applying a filter on an SVG element, which is larger than 4096 pixels, causes this element to be rendered shifted to the left
+        https://bugs.webkit.org/show_bug.cgi?id=144335
+
+        Reviewed by Darin Adler.
+
+        * svg/filters/big-sized-off-viewport-filter-expected.svg: Added.
+        * svg/filters/big-sized-off-viewport-filter.svg: Added.
+        Ensure when applying a filter on a large SVG element, the viewport of the
+        SVG includes the correct drawing part of this element.
+
 2015-05-07  Yoav Weiss  <yoav@yoav.ws>
 
         Handle meta viewport in HTMLPreloadScanner
diff --git a/LayoutTests/svg/filters/big-sized-off-viewport-filter-expected.svg b/LayoutTests/svg/filters/big-sized-off-viewport-filter-expected.svg
new file mode 100644 (file)
index 0000000..a371135
--- /dev/null
@@ -0,0 +1,10 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 500">
+  <filter id="saturate-back">
+    <feColorMatrix in="SourceGraphic" type="saturate" values="1"/>
+  </filter>
+  <g filter="url(#saturate-back)">
+    <rect x="-500" y="0" width="950" height="100%" fill="green"/>
+    <rect x="550" y="0" width="950" height="100%" fill="green"/>
+  </g>
+  <rect x="450" y="0" width="100" height="100%" fill="none" stroke="white" stroke-width="10"/>
+</svg>
diff --git a/LayoutTests/svg/filters/big-sized-off-viewport-filter.svg b/LayoutTests/svg/filters/big-sized-off-viewport-filter.svg
new file mode 100644 (file)
index 0000000..f2fe477
--- /dev/null
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 500">
+  <filter id="saturate-back">
+    <feColorMatrix in="SourceGraphic" type="saturate" values="1"/>
+  </filter>
+  <g filter="url(#saturate-back)">
+    <rect x="-3500" y="0" width="3950" height="100%" fill="green"/>
+    <rect x="550" y="0" width="3950" height="100%" fill="green"/>
+  </g>
+  <!-- Ensure the edges of the rectangles are sharp after clamping the filter image and scaling it up -->
+  <rect x="450" y="0" width="100" height="100%" fill="none" stroke="white" stroke-width="10"/>
+</svg>
index 2b95090..caaac65 100644 (file)
@@ -1,3 +1,109 @@
+2015-05-07  Said Abou-Hallawa  <sabouhallawa@apple.com>
+
+        Applying a filter on an SVG element, which is larger than 4096 pixels, causes this element to be rendered shifted to the left
+        https://bugs.webkit.org/show_bug.cgi?id=144335
+
+        Reviewed by Darin Adler.
+
+        When the SVG element is larger than 4096x4096 pixels and it has a filter,
+        a clipper or a masker, the ImageBuffer which is created for drawing the
+        sourceGraphicBuffer has to be clamped to this size. The reason for this
+        clamping is the FilterEffect simply ignores processing any ImageBuffer
+        larger than this size.
+        
+        The bug was happening because we did not propagate the clamping logic to
+        the FilterEffect. The FilterEffect result ImageBuffer was not clamped as
+        what we do for drawing the sourceGraphicBuffer. If only the destination
+        point is specified, the GraphicsContext::drawImageBuffer() assumes the
+        source and the destination images have the same size which is not true
+        with the clamping.
+        
+        The fix is to add the clamping logic to the FilterEffect. Two places we
+        need to change. (1) FilterEffect::createImageBufferResult() has to apply
+        the same clamping we do in SVGRenderingContext::createImageBuffer(). (2)
+        FilterEffect::drawingRegionOfInputImage() has to consider the clamping 
+        when mapping from absolute coordinates to the ImageBuffer coordinates.
+        
+        Tests: svg/filters/big-sized-off-viewport-filter.svg
+
+        * platform/graphics/ImageBuffer.cpp:
+        (WebCore::ImageBuffer::isSizeClamped):
+        (WebCore::ImageBuffer::clampedSize):
+        (WebCore::ImageBuffer::clampedRect):
+        * platform/graphics/ImageBuffer.h:
+        (WebCore::ImageBuffer::setSpaceSize): Move all the clamping helper methods
+        from SVGRenderingContext and RenderSVGResourceFilter to the ImageBuffer.
+
+        * platform/graphics/filters/FEColorMatrix.cpp:
+        (WebCore::FEColorMatrix::platformApplySoftware): Use logicalSize() of the
+        result image instead of using absolutePaintRect(). The later returns the
+        rectangle of the element without clamping.
+        
+        * platform/graphics/filters/FETile.cpp:
+        (WebCore::FETile::platformApplySoftware):
+        * rendering/svg/RenderSVGResourceClipper.cpp:
+        (WebCore::RenderSVGResourceClipper::applyClippingToContext):
+        * rendering/svg/RenderSVGResourceFilter.cpp:
+        (WebCore::RenderSVGResourceFilter::applyResource):
+        (WebCore::RenderSVGResourceFilter::fitsInMaximumImageSize): Deleted.
+        * rendering/svg/RenderSVGResourceFilter.h:
+        * rendering/svg/RenderSVGResourceGradient.cpp:
+        (WebCore::createMaskAndSwapContextForTextGradient):
+        (WebCore::clipToTextMask):
+        * rendering/svg/RenderSVGResourceMasker.cpp:
+        (WebCore::RenderSVGResourceMasker::applySVGMask):
+        * rendering/svg/RenderSVGResourcePattern.cpp:
+        (WebCore::RenderSVGResourcePattern::buildPattern):
+        (WebCore::RenderSVGResourcePattern::createTileImage): Make the modifications
+        which are needed because of moving the clamping helper methods to ImageBuffer
+        and because of changing the prototype of SVGRenderingContext methods.
+
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::drawingRegionOfInputImage): Consider the clamping
+        when mapping from absolute coordinates to the ImageBuffer coordinates.
+
+        (WebCore::FilterEffect::createImageBufferResult): Apply the same clamping
+        we do in SVGRenderingContext::createImageBuffer() when creating the 
+        FilterEffect result ImageBuffer.
+        
+        (WebCore::FilterEffect::apply):
+        (WebCore::FilterEffect::asUnmultipliedImage):
+        (WebCore::FilterEffect::asPremultipliedImage):
+        (WebCore::FilterEffect::copyUnmultipliedImage):
+        (WebCore::FilterEffect::copyPremultipliedImage):
+        (WebCore::FilterEffect::createUnmultipliedImageResult):
+        (WebCore::FilterEffect::createPremultipliedImageResult):
+        (WebCore::FilterEffect::maxFilterArea): Deleted.
+        (WebCore::FilterEffect::isFilterSizeValid): Deleted.
+        * platform/graphics/filters/FilterEffect.h: Use the new ImageBuffer clamping
+        helper methods and delete the local ones.
+
+        * platform/graphics/transforms/AffineTransform.cpp:
+        (WebCore::AffineTransform::scaleNonUniform):
+        (WebCore::AffineTransform::scale):
+        (WebCore::AffineTransform::translate):
+        * platform/graphics/transforms/AffineTransform.h: Add new scale and translate
+        overloads to AffineTransform.
+        
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::FilterEffectRenderer::updateBackingStoreRect):
+        (WebCore::FilterEffectRendererHelper::beginFilterEffect): Code clean up.
+        
+        * rendering/svg/SVGRenderingContext.cpp:
+        (WebCore::SVGRenderingContext::calculateScreenFontSizeScalingFactor):
+        (WebCore::SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem):
+        Return the AffineTransform instead of passing it through the reference of
+        an argument.
+        
+        (WebCore::SVGRenderingContext::createImageBuffer):
+        (WebCore::SVGRenderingContext::createImageBufferForPattern): Deleted.
+        Code clean up and method rename.
+        
+        (WebCore::SVGRenderingContext::clampedAbsoluteTargetRect): Deleted.
+        (WebCore::SVGRenderingContext::clampedAbsoluteSize): Deleted.
+        * rendering/svg/SVGRenderingContext.h: Move the clamping helper methods to
+        the ImageBuffer class.
+    
 2015-05-07  Beth Dakin  <bdakin@apple.com>
 
         New force-related DOM events should fire in WK1 views
index b384372..1390cdb 100644 (file)
 
 namespace WebCore {
 
+static const float MaxClampedLength = 4096;
+static const float MaxClampedArea = MaxClampedLength * MaxClampedLength;
+
+bool ImageBuffer::isSizeClamped(const FloatSize& size)
+{
+    if (size.width() < 0 && size.height() < 0)
+        return false;
+
+    if (size.isEmpty())
+        return true;
+
+    return floorf(size.height()) * floorf(size.width()) <= MaxClampedArea;
+}
+
+bool ImageBuffer::isSizeClamped(const FloatSize& size, FloatSize& scale)
+{
+    FloatSize scaledSize(size);
+    scaledSize.scale(scale.width(), scale.height());
+
+    if (isSizeClamped(scaledSize))
+        return true;
+
+    // The area of scaled size is bigger than the upper limit, adjust the scale to fit.
+    scale.scale(sqrtf(MaxClampedArea / (scaledSize.width() * scaledSize.height())));
+    ASSERT(isSizeClamped(size, scale));
+    return false;
+}
+
+FloatSize ImageBuffer::clampedSize(const FloatSize& size)
+{
+    return size.shrunkTo(FloatSize(MaxClampedLength, MaxClampedLength));
+}
+
+FloatSize ImageBuffer::clampedSize(const FloatSize& size, FloatSize& scale)
+{
+    if (size.isEmpty())
+        return size;
+
+    FloatSize clampedSize = ImageBuffer::clampedSize(size);
+    scale = FloatSize(clampedSize.width() / size.width(), clampedSize.height() / size.height());
+    ASSERT(isSizeClamped(clampedSize));
+    ASSERT(isSizeClamped(size, scale));
+    return clampedSize;
+}
+
+FloatRect ImageBuffer::clampedRect(const FloatRect& rect)
+{
+    return FloatRect(rect.location(), clampedSize(rect.size()));
+}
+
 #if !USE(CG)
 void ImageBuffer::transformColorSpace(ColorSpace srcColorSpace, ColorSpace dstColorSpace)
 {
index 337be23..320d8df 100644 (file)
@@ -123,10 +123,14 @@ public:
     bool copyToPlatformTexture(GraphicsContext3D&, Platform3DObject, GC3Denum, bool, bool);
 
     FloatSize spaceSize() const { return m_space; }
-    void setSpaceSize(const FloatSize& space)
-    {
-        m_space = space;
-    }
+    void setSpaceSize(const FloatSize& space) { m_space = space; }
+
+    // These functions are used when clamping the ImageBuffer which is created for filter, masker or clipper.
+    static bool isSizeClamped(const FloatSize&);
+    static bool isSizeClamped(const FloatSize&, FloatSize& scale);
+    static FloatSize clampedSize(const FloatSize&);
+    static FloatSize clampedSize(const FloatSize&, FloatSize& scale);
+    static FloatRect clampedRect(const FloatRect&);
 
 private:
 #if USE(CG)
index e1af4a5..363bb38 100644 (file)
@@ -149,7 +149,7 @@ void FEColorMatrix::platformApplySoftware()
 
     resultImage->context()->drawImageBuffer(in->asImageBuffer(), ColorSpaceDeviceRGB, drawingRegionOfInputImage(in->absolutePaintRect()));
 
-    IntRect imageRect(IntPoint(), absolutePaintRect().size());
+    IntRect imageRect(IntPoint(), resultImage->logicalSize());
     RefPtr<Uint8ClampedArray> pixelArray = resultImage->getUnmultipliedImageData(imageRect);
 
     switch (m_type) {
index 62b6247..f0e9b2d 100644 (file)
@@ -63,8 +63,8 @@ void FETile::platformApplySoftware()
         tileRect.scale(filter.filterResolution().width(), filter.filterResolution().height());
     }
 
-    std::unique_ptr<ImageBuffer> tileImage;
-    if (!SVGRenderingContext::createImageBufferForPattern(tileRect, tileRect, tileImage, ColorSpaceDeviceRGB, filter().renderingMode()))
+    auto tileImage = SVGRenderingContext::createImageBuffer(tileRect, tileRect, ColorSpaceDeviceRGB, filter().renderingMode());
+    if (!tileImage)
         return;
 
     GraphicsContext* tileImageContext = tileImage->context();
index fab67a4..bdd6adc 100644 (file)
@@ -36,8 +36,6 @@
 
 namespace WebCore {
 
-static const float kMaxFilterArea = 4096 * 4096;
-
 FilterEffect::FilterEffect(Filter& filter)
     : m_alphaImage(false)
     , m_filter(filter)
@@ -55,19 +53,6 @@ FilterEffect::~FilterEffect()
 {
 }
 
-float FilterEffect::maxFilterArea()
-{
-    return kMaxFilterArea;
-}
-
-bool FilterEffect::isFilterSizeValid(const FloatRect& rect)
-{
-    if (rect.width() < 0 || rect.height() < 0
-        || (rect.height() * rect.width() > kMaxFilterArea))
-        return false;
-    return true;
-}
-
 void FilterEffect::determineAbsolutePaintRect()
 {
     m_absolutePaintRect = IntRect();
@@ -93,8 +78,14 @@ IntRect FilterEffect::requestedRegionOfInputImageData(const IntRect& effectRect)
 
 FloatRect FilterEffect::drawingRegionOfInputImage(const IntRect& srcRect) const
 {
-    return FloatRect(FloatPoint(srcRect.x() - m_absolutePaintRect.x(),
-                            srcRect.y() - m_absolutePaintRect.y()), srcRect.size());
+    ASSERT(hasResult());
+
+    FloatSize scale;
+    ImageBuffer::clampedSize(m_absolutePaintRect.size(), scale);
+
+    AffineTransform transform;
+    transform.scale(scale).translate(-m_absolutePaintRect.location());
+    return transform.mapRect(srcRect);
 }
 
 FilterEffect* FilterEffect::inputEffect(unsigned number) const
@@ -156,7 +147,7 @@ void FilterEffect::apply()
     determineAbsolutePaintRect();
     setResultColorSpace(m_operatingColorSpace);
 
-    if (!isFilterSizeValid(m_absolutePaintRect))
+    if (m_absolutePaintRect.isEmpty() || !ImageBuffer::isSizeClamped(m_absolutePaintRect.size()))
         return;
 
     if (requiresValidPreMultipliedPixels()) {
@@ -321,8 +312,8 @@ ImageBuffer* FilterEffect::openCLImageToImageBuffer()
 
 PassRefPtr<Uint8ClampedArray> FilterEffect::asUnmultipliedImage(const IntRect& rect)
 {
-    ASSERT(isFilterSizeValid(rect));
     IntSize scaledSize(rect.size());
+    ASSERT(ImageBuffer::isSizeClamped(scaledSize));
     scaledSize.scale(m_filter.filterScale());
     RefPtr<Uint8ClampedArray> imageData = Uint8ClampedArray::createUninitialized(scaledSize.width() * scaledSize.height() * 4);
     copyUnmultipliedImage(imageData.get(), rect);
@@ -331,8 +322,8 @@ PassRefPtr<Uint8ClampedArray> FilterEffect::asUnmultipliedImage(const IntRect& r
 
 PassRefPtr<Uint8ClampedArray> FilterEffect::asPremultipliedImage(const IntRect& rect)
 {
-    ASSERT(isFilterSizeValid(rect));
     IntSize scaledSize(rect.size());
+    ASSERT(ImageBuffer::isSizeClamped(scaledSize));
     scaledSize.scale(m_filter.filterScale());
     RefPtr<Uint8ClampedArray> imageData = Uint8ClampedArray::createUninitialized(scaledSize.width() * scaledSize.height() * 4);
     copyPremultipliedImage(imageData.get(), rect);
@@ -397,8 +388,8 @@ void FilterEffect::copyUnmultipliedImage(Uint8ClampedArray* destination, const I
         if (m_imageBufferResult)
             m_unmultipliedImageResult = m_imageBufferResult->getUnmultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
         else {
-            ASSERT(isFilterSizeValid(m_absolutePaintRect));
             IntSize inputSize(m_absolutePaintRect.size());
+            ASSERT(ImageBuffer::isSizeClamped(inputSize));
             inputSize.scale(m_filter.filterScale());
             m_unmultipliedImageResult = Uint8ClampedArray::createUninitialized(inputSize.width() * inputSize.height() * 4);
             unsigned char* sourceComponent = m_premultipliedImageResult->data();
@@ -433,8 +424,8 @@ void FilterEffect::copyPremultipliedImage(Uint8ClampedArray* destination, const
         if (m_imageBufferResult)
             m_premultipliedImageResult = m_imageBufferResult->getPremultipliedImageData(IntRect(IntPoint(), m_absolutePaintRect.size()));
         else {
-            ASSERT(isFilterSizeValid(m_absolutePaintRect));
             IntSize inputSize(m_absolutePaintRect.size());
+            ASSERT(ImageBuffer::isSizeClamped(inputSize));
             inputSize.scale(m_filter.filterScale());
             m_premultipliedImageResult = Uint8ClampedArray::createUninitialized(inputSize.width() * inputSize.height() * 4);
             unsigned char* sourceComponent = m_unmultipliedImageResult->data();
@@ -459,10 +450,13 @@ ImageBuffer* FilterEffect::createImageBufferResult()
     // Only one result type is allowed.
     ASSERT(!hasResult());
     if (m_absolutePaintRect.isEmpty())
-        return 0;
-    m_imageBufferResult = ImageBuffer::create(m_absolutePaintRect.size(), m_filter.filterScale(), m_resultColorSpace, m_filter.renderingMode());
+        return nullptr;
+
+    FloatSize clampedSize = ImageBuffer::clampedSize(m_absolutePaintRect.size());
+    m_imageBufferResult = ImageBuffer::create(clampedSize, m_filter.filterScale(), m_resultColorSpace, m_filter.renderingMode());
     if (!m_imageBufferResult)
-        return 0;
+        return nullptr;
+
     ASSERT(m_imageBufferResult->context());
     return m_imageBufferResult.get();
 }
@@ -471,11 +465,11 @@ Uint8ClampedArray* FilterEffect::createUnmultipliedImageResult()
 {
     // Only one result type is allowed.
     ASSERT(!hasResult());
-    ASSERT(isFilterSizeValid(m_absolutePaintRect));
-
     if (m_absolutePaintRect.isEmpty())
-        return 0;
+        return nullptr;
+
     IntSize resultSize(m_absolutePaintRect.size());
+    ASSERT(ImageBuffer::isSizeClamped(resultSize));
     resultSize.scale(m_filter.filterScale());
     m_unmultipliedImageResult = Uint8ClampedArray::createUninitialized(resultSize.width() * resultSize.height() * 4);
     return m_unmultipliedImageResult.get();
@@ -485,11 +479,11 @@ Uint8ClampedArray* FilterEffect::createPremultipliedImageResult()
 {
     // Only one result type is allowed.
     ASSERT(!hasResult());
-    ASSERT(isFilterSizeValid(m_absolutePaintRect));
-
     if (m_absolutePaintRect.isEmpty())
-        return 0;
+        return nullptr;
+
     IntSize resultSize(m_absolutePaintRect.size());
+    ASSERT(ImageBuffer::isSizeClamped(resultSize));
     resultSize.scale(m_filter.filterScale());
     m_premultipliedImageResult = Uint8ClampedArray::createUninitialized(resultSize.width() * resultSize.height() * 4);
     return m_premultipliedImageResult.get();
index ca7e0af..ced7044 100644 (file)
@@ -58,9 +58,6 @@ class FilterEffect : public RefCounted<FilterEffect> {
 public:
     virtual ~FilterEffect();
 
-    static bool isFilterSizeValid(const FloatRect&);
-    static float maxFilterArea();
-
     void clearResult();
     void clearResultsRecursive();
 
index 306a11e..53647d4 100644 (file)
@@ -172,6 +172,16 @@ AffineTransform& AffineTransform::scale(double sx, double sy)
     return *this;
 }
 
+AffineTransform& AffineTransform::scaleNonUniform(double sx, double sy)
+{
+    return scale(sx, sy);
+}
+
+AffineTransform& AffineTransform::scale(const FloatSize& s)
+{
+    return scale(s.width(), s.height());
+}
+
 // *this = *this * translation
 AffineTransform& AffineTransform::translate(double tx, double ty)
 {
@@ -186,9 +196,9 @@ AffineTransform& AffineTransform::translate(double tx, double ty)
     return *this;
 }
 
-AffineTransform& AffineTransform::scaleNonUniform(double sx, double sy)
+AffineTransform& AffineTransform::translate(const FloatPoint& t)
 {
-    return scale(sx, sy);
+    return translate(t.x(), t.y());
 }
 
 AffineTransform& AffineTransform::rotateFromVector(double x, double y)
index 641db00..2f7817f 100644 (file)
@@ -98,9 +98,11 @@ public:
     WEBCORE_EXPORT AffineTransform& scale(double);
     AffineTransform& scale(double sx, double sy); 
     AffineTransform& scaleNonUniform(double sx, double sy);
+    AffineTransform& scale(const FloatSize&);
     AffineTransform& rotate(double d);
     AffineTransform& rotateFromVector(double x, double y);
     WEBCORE_EXPORT AffineTransform& translate(double tx, double ty);
+    AffineTransform& translate(const FloatPoint&);
     AffineTransform& shear(double sx, double sy);
     AffineTransform& flipX();
     WEBCORE_EXPORT AffineTransform& flipY();
@@ -172,7 +174,7 @@ public:
     {
         return AffineTransform(1, 0, 0, 1, x, y);
     }
-    
+
     // decompose the matrix into its component parts
     typedef struct {
         double scaleX, scaleY;
index f72949d..4c8cadc 100644 (file)
@@ -305,14 +305,14 @@ bool FilterEffectRenderer::build(RenderElement* renderer, const FilterOperations
 
 bool FilterEffectRenderer::updateBackingStoreRect(const FloatRect& filterRect)
 {
-    if (!filterRect.isZero() && FilterEffect::isFilterSizeValid(filterRect)) {
-        FloatRect currentSourceRect = sourceImageRect();
-        if (filterRect != currentSourceRect) {
-            setSourceImageRect(filterRect);
-            return true;
-        }
-    }
-    return false;
+    if (filterRect.isEmpty() || !ImageBuffer::isSizeClamped(filterRect.size()))
+        return false;
+
+    if (filterRect == sourceImageRect())
+        return false;
+
+    setSourceImageRect(filterRect);
+    return true;
 }
 
 void FilterEffectRenderer::allocateBackingStoreIfNeeded()
@@ -401,7 +401,7 @@ bool FilterEffectRendererHelper::beginFilterEffect()
     filter->allocateBackingStoreIfNeeded();
     // Paint into the context that represents the SourceGraphic of the filter.
     GraphicsContext* sourceGraphicsContext = filter->inputContext();
-    if (!sourceGraphicsContext || !FilterEffect::isFilterSizeValid(filter->filterRegion())) {
+    if (!sourceGraphicsContext || filter->filterRegion().isEmpty() || !ImageBuffer::isSizeClamped(filter->filterRegion().size())) {
         // Disable the filters and continue.
         m_haveFilterEffect = false;
         return false;
index d170f28..8b9a628 100644 (file)
@@ -138,11 +138,11 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, c
     if (shouldCreateClipperMaskImage && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
         return true;
 
-    AffineTransform absoluteTransform;
-    SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer, absoluteTransform);
+    AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
 
     if (shouldCreateClipperMaskImage && !repaintRect.isEmpty()) {
-        if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, clipperMaskImage, ColorSpaceDeviceRGB, Unaccelerated))
+        clipperMaskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, ColorSpaceDeviceRGB, Unaccelerated);
+        if (!clipperMaskImage)
             return false;
 
         GraphicsContext* maskContext = clipperMaskImage->context();
index ae33fac..6770e8b 100644 (file)
@@ -96,21 +96,6 @@ std::unique_ptr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFi
     return builder;
 }
 
-bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, FloatSize& scale)
-{
-    FloatSize scaledSize(size);
-    scaledSize.scale(scale.width(), scale.height());
-    float scaledArea = scaledSize.width() * scaledSize.height();
-
-    if (scaledArea <= FilterEffect::maxFilterArea())
-        return true;
-
-    // If area of scaled size is bigger than the upper limit, adjust the scale
-    // to fit.
-    scale.scale(sqrt(FilterEffect::maxFilterArea() / scaledArea));
-    return false;
-}
-
 bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const RenderStyle&, GraphicsContext*& context, unsigned short resourceMode)
 {
     ASSERT(context);
@@ -131,8 +116,7 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
         return false;
 
     // Determine absolute transformation matrix for filter. 
-    AffineTransform absoluteTransform;
-    SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer, absoluteTransform);
+    AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
     if (!absoluteTransform.isInvertible())
         return false;
 
@@ -167,8 +151,8 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
 
     // Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
     FloatRect tempSourceRect = absoluteDrawingRegion;
+    ImageBuffer::isSizeClamped(tempSourceRect.size(), scale);
     tempSourceRect.scale(scale.width(), scale.height());
-    fitsInMaximumImageSize(tempSourceRect.size(), scale);
 
     // Set the scale level in SVGFilter.
     filterData->filter->setFilterResolution(scale);
@@ -182,7 +166,7 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
     FloatRect subRegion = lastEffect->maxEffectRect();
     // At least one FilterEffect has a too big image size,
     // recalculate the effect sizes with new scale factors.
-    if (!fitsInMaximumImageSize(subRegion.size(), scale)) {
+    if (!ImageBuffer::isSizeClamped(subRegion.size(), scale)) {
         filterData->filter->setFilterResolution(scale);
         RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(*lastEffect);
     }
@@ -201,9 +185,10 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
     effectiveTransform.scale(scale.width(), scale.height());
     effectiveTransform.multiply(filterData->shearFreeAbsoluteTransform);
 
-    std::unique_ptr<ImageBuffer> sourceGraphic;
     RenderingMode renderingMode = renderer.frame().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
-    if (!SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, sourceGraphic, ColorSpaceLinearRGB, renderingMode)) {
+
+    auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, ColorSpaceLinearRGB, renderingMode);
+    if (!sourceGraphic) {
         ASSERT(!m_filter.contains(&renderer));
         filterData->savedContext = context;
         m_filter.set(&renderer, WTF::move(filterData));
index c6f5c72..d6ccfbf 100644 (file)
@@ -91,8 +91,6 @@ private:
     virtual const char* renderName() const override { return "RenderSVGResourceFilter"; }
     virtual bool isSVGResourceFilter() const override { return true; }
 
-    bool fitsInMaximumImageSize(const FloatSize&, FloatSize&);
-
     HashMap<RenderObject*, std::unique_ptr<FilterData>> m_filter;
 };
 
index 3a20f68..cbca103 100644 (file)
@@ -58,12 +58,11 @@ static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& con
     auto* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(*object);
     ASSERT(textRootBlock);
 
-    AffineTransform absoluteTransform;
-    SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock, absoluteTransform);
-
+    AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock);
     FloatRect repaintRect = textRootBlock->repaintRectInLocalCoordinates();
-    std::unique_ptr<ImageBuffer> maskImage;
-    if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskImage, ColorSpaceDeviceRGB, Unaccelerated))
+
+    auto maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, ColorSpaceDeviceRGB, Unaccelerated);
+    if (!maskImage)
         return false;
 
     GraphicsContext* maskImageContext = maskImage->context();
@@ -80,10 +79,10 @@ static inline AffineTransform clipToTextMask(GraphicsContext* context, std::uniq
     auto* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(*object);
     ASSERT(textRootBlock);
 
-    AffineTransform absoluteTransform;
-    SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock, absoluteTransform);
+    AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock);
 
     targetRect = textRootBlock->repaintRectInLocalCoordinates();
+
     SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, targetRect, imageBuffer, false);
 
     AffineTransform matrix;
index 293d83c..0115075 100644 (file)
@@ -63,16 +63,14 @@ bool RenderSVGResourceMasker::applySVGMask(RenderElement& renderer, GraphicsCont
         m_masker.set(&renderer, std::make_unique<MaskerData>());
 
     MaskerData* maskerData = m_masker.get(&renderer);
-
-    AffineTransform absoluteTransform;
-    SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer, absoluteTransform);
-
+    AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
     FloatRect repaintRect = renderer.repaintRectInLocalCoordinates();
 
     if (!maskerData->maskImage && !repaintRect.isEmpty()) {
         const SVGRenderStyle& svgStyle = style().svgStyle();
         ColorSpace colorSpace = svgStyle.colorInterpolation() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB;
-        if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskerData->maskImage, colorSpace, Unaccelerated))
+        maskerData->maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, colorSpace, Unaccelerated);
+        if (!maskerData->maskImage)
             return false;
 
         if (!drawContentIntoMaskImage(maskerData, colorSpace, &renderer))
index 7bb6ef6..4bc0d95 100644 (file)
@@ -70,20 +70,19 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, uns
 
     // If we couldn't determine the pattern content element root, stop here.
     if (!m_attributes.patternContentElement())
-        return 0;
+        return nullptr;
 
     // An empty viewBox disables rendering.
     if (m_attributes.hasViewBox() && m_attributes.viewBox().isEmpty())
-        return 0;
+        return nullptr;
 
     // Compute all necessary transformations to build the tile image & the pattern.
     FloatRect tileBoundaries;
     AffineTransform tileImageTransform;
     if (!buildTileImageTransform(renderer, m_attributes, patternElement(), tileBoundaries, tileImageTransform))
-        return 0;
+        return nullptr;
 
-    AffineTransform absoluteTransformIgnoringRotation;
-    SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer, absoluteTransformIgnoringRotation);
+    AffineTransform absoluteTransformIgnoringRotation = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
 
     // Ignore 2D rotation, as it doesn't affect the size of the tile.
     SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
@@ -95,13 +94,13 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, uns
         static_cast<float>(m_attributes.patternTransform().yScale()));
 
     // Build tile image.
-    std::unique_ptr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries);
+    auto tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries);
     if (!tileImage)
-        return 0;
+        return nullptr;
 
     RefPtr<Image> copiedImage = tileImage->copyImage(CopyBackingStore);
     if (!copiedImage)
-        return 0;
+        return nullptr;
 
     // Build pattern.
     auto patternData = std::make_unique<PatternData>();
@@ -233,11 +232,9 @@ bool RenderSVGResourcePattern::buildTileImageTransform(RenderElement& renderer,
 
 std::unique_ptr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries) const
 {
-    clampedAbsoluteTileBoundaries = SVGRenderingContext::clampedAbsoluteTargetRect(absoluteTileBoundaries);
-
-    std::unique_ptr<ImageBuffer> tileImage;
-
-    if (!SVGRenderingContext::createImageBufferForPattern(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB, Unaccelerated))
+    clampedAbsoluteTileBoundaries = ImageBuffer::clampedRect(absoluteTileBoundaries);
+    auto tileImage = SVGRenderingContext::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, ColorSpaceDeviceRGB, Unaccelerated);
+    if (!tileImage)
         return nullptr;
 
     GraphicsContext* tileImageContext = tileImage->context();
index 6c12e1c..926f23b 100644 (file)
@@ -39,8 +39,6 @@
 #include "SVGResources.h"
 #include "SVGResourcesCache.h"
 
-static int kMaxImageBufferSize = 4096;
-
 namespace WebCore {
 
 static inline bool isRenderingMaskImage(const RenderObject& object)
@@ -204,14 +202,13 @@ static AffineTransform& currentContentTransformation()
 
 float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObject& renderer)
 {
-    AffineTransform ctm;
-    calculateTransformationToOutermostCoordinateSystem(renderer, ctm);
+    AffineTransform ctm = calculateTransformationToOutermostCoordinateSystem(renderer);
     return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
 }
 
-void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject& renderer, AffineTransform& absoluteTransform)
+AffineTransform SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject& renderer)
 {
-    absoluteTransform = currentContentTransformation();
+    AffineTransform absoluteTransform = currentContentTransformation();
 
     float deviceScaleFactor = renderer.document().deviceScaleFactor();
     // Walk up the render tree, accumulating SVG transforms.
@@ -237,53 +234,53 @@ void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(con
     }
 
     absoluteTransform.scale(deviceScaleFactor);
+    return absoluteTransform;
 }
 
-bool SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, std::unique_ptr<ImageBuffer>& imageBuffer, ColorSpace colorSpace, RenderingMode renderingMode)
+std::unique_ptr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, ColorSpace colorSpace, RenderingMode renderingMode)
 {
     IntRect paintRect = calculateImageBufferRect(targetRect, absoluteTransform);
     // Don't create empty ImageBuffers.
     if (paintRect.isEmpty())
-        return false;
+        return nullptr;
 
-    IntSize clampedSize = clampedAbsoluteSize(paintRect.size());
-    std::unique_ptr<ImageBuffer> image = ImageBuffer::create(clampedSize, 1, colorSpace, renderingMode);
-    if (!image)
-        return false;
+    FloatSize scale;
+    FloatSize clampedSize = ImageBuffer::clampedSize(paintRect.size(), scale);
 
-    GraphicsContext* imageContext = image->context();
-    ASSERT(imageContext);
+    auto imageBuffer = ImageBuffer::create(clampedSize, 1, colorSpace, renderingMode);
+    if (!imageBuffer)
+        return nullptr;
 
-    imageContext->scale(FloatSize(static_cast<float>(clampedSize.width()) / paintRect.width(),
-                                  static_cast<float>(clampedSize.height()) / paintRect.height()));
-    imageContext->translate(-paintRect.x(), -paintRect.y());
-    imageContext->concatCTM(absoluteTransform);
+    AffineTransform transform;
+    transform.scale(scale).translate(-paintRect.location()).multiply(absoluteTransform);
 
-    imageBuffer = WTF::move(image);
-    return true;
+    GraphicsContext* imageContext = imageBuffer->context();
+    ASSERT(imageContext);
+    imageContext->concatCTM(transform);
+
+    return imageBuffer;
 }
 
-bool SVGRenderingContext::createImageBufferForPattern(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, std::unique_ptr<ImageBuffer>& imageBuffer, ColorSpace colorSpace, RenderingMode renderingMode)
+std::unique_ptr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, ColorSpace colorSpace, RenderingMode renderingMode)
 {
-    IntSize imageSize(roundedIntSize(clampedAbsoluteTargetRect.size()));
-    IntSize unclampedImageSize(roundedIntSize(absoluteTargetRect.size()));
+    IntSize clampedSize = roundedIntSize(clampedRect.size());
+    IntSize unclampedSize = roundedIntSize(targetRect.size());
 
     // Don't create empty ImageBuffers.
-    if (imageSize.isEmpty())
-        return false;
+    if (clampedSize.isEmpty())
+        return nullptr;
 
-    std::unique_ptr<ImageBuffer> image = ImageBuffer::create(imageSize, 1, colorSpace, renderingMode);
-    if (!image)
-        return false;
+    auto imageBuffer = ImageBuffer::create(clampedSize, 1, colorSpace, renderingMode);
+    if (!imageBuffer)
+        return nullptr;
 
-    GraphicsContext* imageContext = image->context();
+    GraphicsContext* imageContext = imageBuffer->context();
     ASSERT(imageContext);
 
     // Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
-    imageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTargetRect.width(), unclampedImageSize.height() / absoluteTargetRect.height()));
+    imageContext->scale(FloatSize(unclampedSize.width() / targetRect.width(), unclampedSize.height() / targetRect.height()));
 
-    imageBuffer = WTF::move(image);
-    return true;
+    return imageBuffer;
 }
 
 void SVGRenderingContext::renderSubtreeToImageBuffer(ImageBuffer* image, RenderElement& item, const AffineTransform& subtreeContentTransformation)
@@ -322,18 +319,6 @@ void SVGRenderingContext::clipToImageBuffer(GraphicsContext* context, const Affi
         imageBuffer.reset();
 }
 
-FloatRect SVGRenderingContext::clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect)
-{
-    const FloatSize maxImageBufferSize(kMaxImageBufferSize, kMaxImageBufferSize);
-    return FloatRect(absoluteTargetRect.location(), absoluteTargetRect.size().shrunkTo(maxImageBufferSize));
-}
-
-IntSize SVGRenderingContext::clampedAbsoluteSize(const IntSize& absoluteSize)
-{
-    const IntSize maxImageBufferSize(kMaxImageBufferSize, kMaxImageBufferSize);
-    return absoluteSize.shrunkTo(maxImageBufferSize);
-}
-
 void SVGRenderingContext::clear2DRotation(AffineTransform& transform)
 {
     AffineTransform::DecomposedType decomposition;
index d7c781c..9a23c25 100644 (file)
@@ -71,17 +71,14 @@ public:
     void prepareToRenderSVGContent(RenderElement&, PaintInfo&, NeedsGraphicsContextSave = DontSaveGraphicsContext);
     bool isRenderingPrepared() const { return m_renderingFlags & RenderingPrepared; }
 
-    static bool createImageBuffer(const FloatRect& paintRect, const AffineTransform& absoluteTransform, std::unique_ptr<ImageBuffer>&, ColorSpace, RenderingMode);
-    // Patterns need a different float-to-integer coordinate mapping.
-    static bool createImageBufferForPattern(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, std::unique_ptr<ImageBuffer>&, ColorSpace, RenderingMode);
+    static std::unique_ptr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, ColorSpace, RenderingMode);
+    static std::unique_ptr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, ColorSpace, RenderingMode);
 
     static void renderSubtreeToImageBuffer(ImageBuffer*, RenderElement&, const AffineTransform&);
     static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& targetRect, std::unique_ptr<ImageBuffer>&, bool safeToClear);
 
     static float calculateScreenFontSizeScalingFactor(const RenderObject&);
-    static void calculateTransformationToOutermostCoordinateSystem(const RenderObject&, AffineTransform& absoluteTransform);
-    static IntSize clampedAbsoluteSize(const IntSize&);
-    static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);
+    static AffineTransform calculateTransformationToOutermostCoordinateSystem(const RenderObject&);
     static void clear2DRotation(AffineTransform&);
 
     static IntRect calculateImageBufferRect(const FloatRect& targetRect, const AffineTransform& absoluteTransform)