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

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

Issue 9235065: Merge 105978 - crash in WebCore::RenderSVGContainer::paint (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/963/
Patch Set: Created 8 years, 11 months 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
Index: Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
===================================================================
--- Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp (revision 106008)
+++ Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp (working copy)
@@ -54,7 +54,6 @@
RenderSVGResourceClipper::RenderSVGResourceClipper(SVGClipPathElement* node)
: RenderSVGResourceContainer(node)
- , m_invalidationBlocked(false)
{
}
@@ -69,9 +68,6 @@
void RenderSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidation)
{
- if (m_invalidationBlocked)
- return;
-
m_clipBoundaries = FloatRect();
if (!m_clipper.isEmpty()) {
deleteAllValues(m_clipper);
@@ -84,9 +80,6 @@
void RenderSVGResourceClipper::removeClientFromCache(RenderObject* client, bool markForInvalidation)
{
ASSERT(client);
- if (m_invalidationBlocked)
- return;
-
if (m_clipper.contains(client))
delete m_clipper.take(client);
@@ -199,7 +192,10 @@
}
}
- drawContentIntoMaskImage(clipperData, objectBoundingBox);
+ if (!drawContentIntoMaskImage(clipperData, objectBoundingBox)) {
+ stateSaver.restore();
+ clipperData->clipMaskImage.clear();
+ }
}
if (!clipperData->clipMaskImage)
@@ -211,6 +207,7 @@
bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData, const FloatRect& objectBoundingBox)
{
+ ASSERT(frame());
ASSERT(clipperData);
ASSERT(clipperData->clipMaskImage);
@@ -225,11 +222,23 @@
maskContext->concatCTM(maskContentTransformation);
}
+ // Switch to a paint behavior where all children of this <clipPath> will be rendered using special constraints:
+ // - fill-opacity/stroke-opacity/opacity set to 1
+ // - masker/filter not applied when rendering the children
+ // - fill is set to the initial fill paint server (solid, black)
+ // - stroke is set to the initial stroke paint server (none)
+ PaintBehavior oldBehavior = frame()->view()->paintBehavior();
+ frame()->view()->setPaintBehavior(oldBehavior | PaintBehaviorRenderingSVGMask);
+
// Draw all clipPath children into a global mask.
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
continue;
+ if (renderer->needsLayout()) {
+ frame()->view()->setPaintBehavior(oldBehavior);
+ return false;
+ }
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
@@ -249,35 +258,15 @@
if (!renderer->isSVGShape() && !renderer->isSVGText())
continue;
- // Save the old RenderStyle of the current object for restoring after drawing
- // it to the MaskImage. The new intermediate RenderStyle needs to inherit from
- // the old one.
- RefPtr<RenderStyle> oldRenderStyle = renderer->style();
- RefPtr<RenderStyle> newRenderStyle = RenderStyle::clone(oldRenderStyle.get());
- SVGRenderStyle* svgStyle = newRenderStyle.get()->accessSVGStyle();
- svgStyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri());
- svgStyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri());
- svgStyle->setFillRule(newClipRule);
- newRenderStyle.get()->setOpacity(1);
- svgStyle->setFillOpacity(1);
- svgStyle->setStrokeOpacity(1);
- svgStyle->setFilterResource(String());
- svgStyle->setMaskerResource(String());
+ maskContext->setFillRule(newClipRule);
- // The setStyle() call results in a styleDidChange() call, which in turn invalidations the resources.
- // As we're mutating the resource on purpose, block updates until we've resetted the style again.
- m_invalidationBlocked = true;
- renderer->setStyle(newRenderStyle.release());
-
// In the case of a <use> element, we obtained its renderere above, to retrieve its clipRule.
// We have to pass the <use> renderer itself to renderSubtreeToImageBuffer() to apply it's x/y/transform/etc. values when rendering.
// So if isUseElement is true, refetch the childNode->renderer(), as renderer got overriden above.
SVGImageBufferTools::renderSubtreeToImageBuffer(clipperData->clipMaskImage.get(), isUseElement ? childNode->renderer() : renderer, maskContentTransformation);
-
- renderer->setStyle(oldRenderStyle.release());
- m_invalidationBlocked = false;
}
+ frame()->view()->setPaintBehavior(oldBehavior);
return true;
}
« no previous file with comments | « Source/WebCore/rendering/svg/RenderSVGResourceClipper.h ('k') | Source/WebCore/rendering/svg/RenderSVGResourceMasker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698