Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / svg / RenderSVGResourcePattern.cpp
index cf6889d..2848697 100644 (file)
 
 #include "core/rendering/svg/RenderSVGResourcePattern.h"
 
+#include "core/dom/ElementTraversal.h"
 #include "core/rendering/svg/SVGRenderSupport.h"
 #include "core/rendering/svg/SVGRenderingContext.h"
 #include "core/svg/SVGFitToViewBox.h"
 #include "platform/graphics/GraphicsContext.h"
 
-namespace WebCore {
+namespace blink {
 
 const RenderSVGResourceType RenderSVGResourcePattern::s_resourceType = PatternResourceType;
 
@@ -41,35 +42,23 @@ void RenderSVGResourcePattern::removeAllClientsFromCache(bool markForInvalidatio
 {
     m_patternMap.clear();
     m_shouldCollectPatternAttributes = true;
-    markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
+    markAllClientsForInvalidation(markForInvalidation ? PaintInvalidation : ParentOnlyInvalidation);
 }
 
 void RenderSVGResourcePattern::removeClientFromCache(RenderObject* client, bool markForInvalidation)
 {
     ASSERT(client);
     m_patternMap.remove(client);
-    markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
+    markClientForInvalidation(client, markForInvalidation ? PaintInvalidation : ParentOnlyInvalidation);
 }
 
-PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsigned short resourceMode)
+PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, const SVGPatternElement* patternElement)
 {
     ASSERT(object);
     PatternData* currentData = m_patternMap.get(object);
     if (currentData && currentData->pattern)
         return currentData;
 
-    SVGPatternElement* patternElement = toSVGPatternElement(element());
-    if (!patternElement)
-        return 0;
-
-    if (m_shouldCollectPatternAttributes) {
-        patternElement->synchronizeAnimatedSVGAttribute(anyQName());
-
-        m_attributes = PatternAttributes();
-        patternElement->collectPatternAttributes(m_attributes);
-        m_shouldCollectPatternAttributes = false;
-    }
-
     // If we couldn't determine the pattern content element root, stop here.
     if (!m_attributes.patternContentElement())
         return 0;
@@ -90,14 +79,13 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
     // Ignore 2D rotation, as it doesn't affect the size of the tile.
     SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
     FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries);
-    FloatRect clampedAbsoluteTileBoundaries;
 
     // Scale the tile size to match the scale level of the patternTransform.
     absoluteTileBoundaries.scale(static_cast<float>(m_attributes.patternTransform().xScale()),
         static_cast<float>(m_attributes.patternTransform().yScale()));
 
     // Build tile image.
-    OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries);
+    OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform);
     if (!tileImage)
         return 0;
 
@@ -107,7 +95,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
 
     // Build pattern.
     OwnPtr<PatternData> patternData = adoptPtr(new PatternData);
-    patternData->pattern = Pattern::create(copiedImage, true, true);
+    patternData->pattern = Pattern::createBitmapPattern(copiedImage);
 
     // Compute pattern space transformation.
     const IntSize tileImageSize = tileImage->size();
@@ -118,14 +106,6 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
     if (!patternTransform.isIdentity())
         patternData->transform = patternTransform * patternData->transform;
 
-    // Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows.
-    if (resourceMode & ApplyToTextMode) {
-        AffineTransform additionalTextTransformation;
-        if (shouldTransformOnTextPainting(object, additionalTextTransformation))
-            patternData->transform *= additionalTextTransformation;
-    }
-    patternData->pattern->setPatternSpaceTransform(patternData->transform);
-
     // 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.
@@ -141,30 +121,42 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
 
     clearInvalidationMask();
 
+    SVGPatternElement* patternElement = toSVGPatternElement(element());
+    if (!patternElement)
+        return false;
+
+    if (m_shouldCollectPatternAttributes) {
+        patternElement->synchronizeAnimatedSVGAttribute(anyQName());
+
+        m_attributes = PatternAttributes();
+        patternElement->collectPatternAttributes(m_attributes);
+        m_shouldCollectPatternAttributes = false;
+    }
+
     // Spec: When the geometry of the applicable element has no width or height and objectBoundingBox is specified,
     // then the given effect (e.g. a gradient or a filter) will be ignored.
     FloatRect objectBoundingBox = object->objectBoundingBox();
     if (m_attributes.patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
         return false;
 
-    PatternData* patternData = buildPattern(object, resourceMode);
+    PatternData* patternData = buildPattern(object, patternElement);
     if (!patternData)
         return false;
 
+    const SVGRenderStyle& svgStyle = style->svgStyle();
+
+    AffineTransform computedPatternSpaceTransform = computeResourceSpaceTransform(object, patternData->transform, svgStyle, resourceMode);
+    patternData->pattern->setPatternSpaceTransform(computedPatternSpaceTransform);
+
     // Draw pattern
     context->save();
 
-    const SVGRenderStyle* svgStyle = style->svgStyle();
-    ASSERT(svgStyle);
-
     if (resourceMode & ApplyToFillMode) {
-        context->setAlphaAsFloat(svgStyle->fillOpacity());
+        context->setAlphaAsFloat(svgStyle.fillOpacity());
         context->setFillPattern(patternData->pattern);
-        context->setFillRule(svgStyle->fillRule());
+        context->setFillRule(svgStyle.fillRule());
     } else if (resourceMode & ApplyToStrokeMode) {
-        if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
-            patternData->pattern->setPatternSpaceTransform(transformOnNonScalingStroke(object, patternData->transform));
-        context->setAlphaAsFloat(svgStyle->strokeOpacity());
+        context->setAlphaAsFloat(svgStyle.strokeOpacity());
         context->setStrokePattern(patternData->pattern);
         SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
     }
@@ -179,24 +171,9 @@ bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle*
     return true;
 }
 
-void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context, unsigned short resourceMode, const Path* path, const RenderSVGShape* shape)
+void RenderSVGResourcePattern::postApplyResource(RenderObject*, GraphicsContext*& context)
 {
     ASSERT(context);
-    ASSERT(resourceMode != ApplyToDefaultMode);
-
-    if (resourceMode & ApplyToFillMode) {
-        if (path)
-            context->fillPath(*path);
-        else if (shape)
-            shape->fillShape(context);
-    }
-    if (resourceMode & ApplyToStrokeMode) {
-        if (path)
-            context->strokePath(*path);
-        else if (shape)
-            shape->strokeShape(context);
-    }
-
     context->restore();
 }
 
@@ -236,10 +213,9 @@ bool RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer,
 PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes,
                                                                   const FloatRect& tileBoundaries,
                                                                   const FloatRect& absoluteTileBoundaries,
-                                                                  const AffineTransform& tileImageTransform,
-                                                                  FloatRect& clampedAbsoluteTileBoundaries) const
+                                                                  const AffineTransform& tileImageTransform) const
 {
-    clampedAbsoluteTileBoundaries = SVGRenderingContext::clampedAbsoluteTargetRect(absoluteTileBoundaries);
+    FloatRect clampedAbsoluteTileBoundaries = SVGRenderingContext::clampedAbsoluteTargetRect(absoluteTileBoundaries);
 
     IntSize imageSize(roundedIntSize(clampedAbsoluteTileBoundaries.size()));
     if (imageSize.isEmpty())
@@ -251,11 +227,12 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternA
     GraphicsContext* tileImageContext = tileImage->context();
     ASSERT(tileImageContext);
     IntSize unclampedImageSize(roundedIntSize(absoluteTileBoundaries.size()));
-    tileImageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTileBoundaries.width(), unclampedImageSize.height() / absoluteTileBoundaries.height()));
+    tileImageContext->scale(unclampedImageSize.width() / absoluteTileBoundaries.width(), unclampedImageSize.height() / absoluteTileBoundaries.height());
 
     // The image buffer represents the final rendered size, so the content has to be scaled (to avoid pixelation).
-    tileImageContext->scale(FloatSize(clampedAbsoluteTileBoundaries.width() / tileBoundaries.width(),
-                                      clampedAbsoluteTileBoundaries.height() / tileBoundaries.height()));
+    tileImageContext->scale(
+        clampedAbsoluteTileBoundaries.width() / tileBoundaries.width(),
+        clampedAbsoluteTileBoundaries.height() / tileBoundaries.height());
 
     // Apply tile image transformations.
     if (!tileImageTransform.isIdentity())
@@ -266,8 +243,8 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternA
         contentTransformation = tileImageTransform;
 
     // Draw the content into the ImageBuffer.
-    for (Element* element = ElementTraversal::firstWithin(*attributes.patternContentElement()); element; element = ElementTraversal::nextSibling(*element)) {
-        if (!element->isSVGElement() || !element->renderer())
+    for (SVGElement* element = Traversal<SVGElement>::firstChild(*attributes.patternContentElement()); element; element = Traversal<SVGElement>::nextSibling(*element)) {
+        if (!element->renderer())
             continue;
         if (element->renderer()->needsLayout())
             return nullptr;