| 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;
|
| }
|
|
|
|
|