Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(223)

Unified Diff: Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp

Issue 11421227: Merge 136250 (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/1312/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/WebCore/rendering/svg/RenderSVGResourcePattern.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
===================================================================
--- Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp (revision 136569)
+++ Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp (working copy)
@@ -55,20 +55,15 @@
markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
-bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
+PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsigned short resourceMode)
{
- ASSERT(object);
- ASSERT(style);
- ASSERT(context);
- ASSERT(resourceMode != ApplyToDefaultMode);
+ PatternData* currentData = m_patternMap.get(object);
+ if (currentData && currentData->pattern)
+ return currentData;
- // Be sure to synchronize all SVG properties on the patternElement _before_ processing any further.
- // Otherwhise the call to collectPatternAttributes() below, may cause the SVG DOM property
- // synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our
- // PatternData object! Leaving out the line below will cause svg/dynamic-updates/SVGPatternElement-svgdom* to crash.
SVGPatternElement* patternElement = static_cast<SVGPatternElement*>(node());
if (!patternElement)
- return false;
+ return 0;
if (m_shouldCollectPatternAttributes) {
patternElement->updateAnimatedSVGAttribute(anyQName());
@@ -78,71 +73,81 @@
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;
+ // If we couldn't determine the pattern content element root, stop here.
+ if (!m_attributes.patternContentElement())
+ return 0;
- OwnPtr<PatternData>& patternData = m_patternMap.add(object, nullptr).iterator->value;
- if (!patternData)
- patternData = adoptPtr(new PatternData);
+ // 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 (!patternData->pattern) {
- // If we couldn't determine the pattern content element root, stop here.
- if (!m_attributes.patternContentElement())
- return false;
+ AffineTransform absoluteTransformIgnoringRotation;
+ SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransformIgnoringRotation);
- // Compute all necessary transformations to build the tile image & the pattern.
- FloatRect tileBoundaries;
- AffineTransform tileImageTransform;
- if (!buildTileImageTransform(object, m_attributes, patternElement, tileBoundaries, tileImageTransform))
- return false;
+ // Ignore 2D rotation, as it doesn't affect the size of the tile.
+ SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
+ FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries);
+ FloatRect clampedAbsoluteTileBoundaries;
- AffineTransform absoluteTransformIgnoringRotation;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransformIgnoringRotation);
+ // 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()));
- // Ignore 2D rotation, as it doesn't affect the size of the tile.
- SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
- FloatRect absoluteTileBoundaries = absoluteTransformIgnoringRotation.mapRect(tileBoundaries);
- FloatRect clampedAbsoluteTileBoundaries;
+ // Build tile image.
+ OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries);
+ if (!tileImage)
+ return 0;
- // 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()));
+ RefPtr<Image> copiedImage = tileImage->copyImage(CopyBackingStore);
+ if (!copiedImage)
+ return 0;
- // Build tile image.
- OwnPtr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries);
- if (!tileImage)
- return false;
+ // Build pattern.
+ OwnPtr<PatternData> patternData = adoptPtr(new PatternData);
+ patternData->pattern = Pattern::create(copiedImage, true, true);
- RefPtr<Image> copiedImage = tileImage->copyImage(CopyBackingStore);
- if (!copiedImage)
- return false;
+ // Compute pattern space transformation.
+ const IntSize tileImageSize = tileImage->logicalSize();
+ patternData->transform.translate(tileBoundaries.x(), tileBoundaries.y());
+ patternData->transform.scale(tileBoundaries.width() / tileImageSize.width(), tileBoundaries.height() / tileImageSize.height());
- // Build pattern.
- patternData->pattern = Pattern::create(copiedImage, true, true);
- if (!patternData->pattern)
- return false;
+ AffineTransform patternTransform = m_attributes.patternTransform();
+ if (!patternTransform.isIdentity())
+ patternData->transform = patternTransform * patternData->transform;
- // Compute pattern space transformation.
- const IntSize tileImageSize = tileImage->logicalSize();
- patternData->transform.translate(tileBoundaries.x(), tileBoundaries.y());
- patternData->transform.scale(tileBoundaries.width() / tileImageSize.width(), tileBoundaries.height() / tileImageSize.height());
+ // 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);
- AffineTransform patternTransform = m_attributes.patternTransform();
- if (!patternTransform.isIdentity())
- patternData->transform = patternTransform * 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.
+ return m_patternMap.set(object, patternData.release()).iterator->value.get();
+}
- // 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);
- }
+bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
+{
+ ASSERT(object);
+ ASSERT(style);
+ ASSERT(context);
+ ASSERT(resourceMode != ApplyToDefaultMode);
+ // 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);
+ if (!patternData)
+ return false;
+
// Draw pattern
context->save();
« no previous file with comments | « Source/WebCore/rendering/svg/RenderSVGResourcePattern.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698