Applying a filter on an SVG element, which is larger than 4096 pixels, causes this...
[WebKit-https.git] / Source / WebCore / rendering / svg / RenderSVGResourcePattern.cpp
index 7dbe204..4bc0d95 100644 (file)
 
 namespace WebCore {
 
-RenderSVGResourceType RenderSVGResourcePattern::s_resourceType = PatternResourceType;
-
-RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement& element, PassRef<RenderStyle> style)
-    : RenderSVGResourceContainer(element, std::move(style))
+RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement& element, Ref<RenderStyle>&& style)
+    : RenderSVGResourceContainer(element, WTF::move(style))
     , m_shouldCollectPatternAttributes(true)
 {
 }
 
 SVGPatternElement& RenderSVGResourcePattern::patternElement() const
 {
-    return toSVGPatternElement(RenderSVGResourceContainer::element());
+    return downcast<SVGPatternElement>(RenderSVGResourceContainer::element());
 }
 
 void RenderSVGResourcePattern::removeAllClientsFromCache(bool markForInvalidation)
@@ -56,9 +54,9 @@ void RenderSVGResourcePattern::removeClientFromCache(RenderElement& client, bool
     markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
 }
 
-PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsigned short resourceMode)
+PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, unsigned short resourceMode)
 {
-    PatternData* currentData = m_patternMap.get(object);
+    PatternData* currentData = m_patternMap.get(&renderer);
     if (currentData && currentData->pattern)
         return currentData;
 
@@ -72,20 +70,19 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
 
     // 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(object, m_attributes, patternElement(), tileBoundaries, tileImageTransform))
-        return 0;
+    if (!buildTileImageTransform(renderer, m_attributes, patternElement(), tileBoundaries, tileImageTransform))
+        return nullptr;
 
-    AffineTransform absoluteTransformIgnoringRotation;
-    SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*object, absoluteTransformIgnoringRotation);
+    AffineTransform absoluteTransformIgnoringRotation = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
 
     // Ignore 2D rotation, as it doesn't affect the size of the tile.
     SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
@@ -97,16 +94,16 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
         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.
-    OwnPtr<PatternData> patternData = adoptPtr(new PatternData);
+    auto patternData = std::make_unique<PatternData>();
     patternData->pattern = Pattern::create(copiedImage, true, true);
 
     // Compute pattern space transformation.
@@ -121,7 +118,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
     // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows.
     if (resourceMode & ApplyToTextMode) {
         AffineTransform additionalTextTransformation;
-        if (shouldTransformOnTextPainting(object, additionalTextTransformation))
+        if (shouldTransformOnTextPainting(renderer, additionalTextTransformation))
             patternData->transform *= additionalTextTransformation;
     }
     patternData->pattern->setPatternSpaceTransform(patternData->transform);
@@ -129,7 +126,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
     // Various calls above may trigger invalidations in some fringe cases (ImageBuffer allocation
     // failures in the SVG image cache for example). To avoid having our PatternData deleted by
     // removeAllClientsFromCache(), we only make it visible in the cache at the very end.
-    return m_patternMap.set(object, patternData.release()).iterator->value.get();
+    return m_patternMap.set(&renderer, WTF::move(patternData)).iterator->value.get();
 }
 
 bool RenderSVGResourcePattern::applyResource(RenderElement& renderer, const RenderStyle& style, GraphicsContext*& context, unsigned short resourceMode)
@@ -143,7 +140,7 @@ bool RenderSVGResourcePattern::applyResource(RenderElement& renderer, const Rend
     if (m_attributes.patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
         return false;
 
-    PatternData* patternData = buildPattern(&renderer, resourceMode);
+    PatternData* patternData = buildPattern(renderer, resourceMode);
     if (!patternData)
         return false;
 
@@ -154,13 +151,13 @@ bool RenderSVGResourcePattern::applyResource(RenderElement& renderer, const Rend
 
     if (resourceMode & ApplyToFillMode) {
         context->setAlpha(svgStyle.fillOpacity());
-        context->setFillPattern(patternData->pattern);
+        context->setFillPattern(*patternData->pattern);
         context->setFillRule(svgStyle.fillRule());
     } else if (resourceMode & ApplyToStrokeMode) {
         if (svgStyle.vectorEffect() == VE_NON_SCALING_STROKE)
             patternData->pattern->setPatternSpaceTransform(transformOnNonScalingStroke(&renderer, patternData->transform));
         context->setAlpha(svgStyle.strokeOpacity());
-        context->setStrokePattern(patternData->pattern);
+        context->setStrokePattern(*patternData->pattern);
         SVGRenderSupport::applyStrokeStyleToContext(context, style, renderer);
     }
 
@@ -211,15 +208,13 @@ static inline FloatRect calculatePatternBoundaries(const PatternAttributes& attr
     return SVGLengthContext::resolveRectangle(&patternElement, attributes.patternUnits(), objectBoundingBox, attributes.x(), attributes.y(), attributes.width(), attributes.height());
 }
 
-bool RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer,
+bool RenderSVGResourcePattern::buildTileImageTransform(RenderElement& renderer,
                                                        const PatternAttributes& attributes,
                                                        const SVGPatternElement& patternElement,
                                                        FloatRect& patternBoundaries,
                                                        AffineTransform& tileImageTransform) const
 {
-    ASSERT(renderer);
-
-    FloatRect objectBoundingBox = renderer->objectBoundingBox();
+    FloatRect objectBoundingBox = renderer.objectBoundingBox();
     patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement); 
     if (patternBoundaries.width() <= 0 || patternBoundaries.height() <= 0)
         return false;
@@ -237,11 +232,9 @@ bool RenderSVGResourcePattern::buildTileImageTransform(RenderObject* 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();