summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/RenderSVGResourceMasker.cpp
diff options
context:
space:
mode:
authorKristian Monsen <kristianm@google.com>2010-05-21 16:53:46 +0100
committerKristian Monsen <kristianm@google.com>2010-05-25 10:24:15 +0100
commit6c2af9490927c3c5959b5cb07461b646f8b32f6c (patch)
treef7111b9b22befab472616c1d50ec94eb50f1ec8c /WebCore/rendering/RenderSVGResourceMasker.cpp
parenta149172322a9067c14e8b474a53e63649aa17cad (diff)
downloadexternal_webkit-6c2af9490927c3c5959b5cb07461b646f8b32f6c.zip
external_webkit-6c2af9490927c3c5959b5cb07461b646f8b32f6c.tar.gz
external_webkit-6c2af9490927c3c5959b5cb07461b646f8b32f6c.tar.bz2
Merge WebKit at r59636: Initial merge by git
Change-Id: I59b289c4e6b18425f06ce41cc9d34c522515de91
Diffstat (limited to 'WebCore/rendering/RenderSVGResourceMasker.cpp')
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp74
1 files changed, 51 insertions, 23 deletions
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index abf8e48..2bfb283 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -19,6 +19,7 @@
*/
#include "config.h"
+#if ENABLE(SVG)
#include "RenderSVGResourceMasker.h"
#include "AffineTransform.h"
@@ -65,6 +66,7 @@ void RenderSVGResourceMasker::invalidateClients()
deleteAllValues(m_masker);
m_masker.clear();
+ m_maskBoundaries = FloatRect();
}
void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
@@ -111,14 +113,6 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
return true;
}
-FloatRect RenderSVGResourceMasker::resourceBoundingBox(const FloatRect& objectBoundingBox) const
-{
- if (SVGMaskElement* element = static_cast<SVGMaskElement*>(node()))
- return element->maskBoundingBox(objectBoundingBox);
-
- return FloatRect();
-}
-
void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object)
{
FloatRect objectBoundingBox = object->objectBoundingBox();
@@ -129,19 +123,11 @@ void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGM
maskerData->emptyMask = true;
return;
}
+
+ if (m_maskBoundaries.isEmpty())
+ calculateMaskContentRepaintRect();
- // Calculate the smallest rect for the mask ImageBuffer.
- FloatRect repaintRect;
- Vector<RenderObject*> rendererList;
- for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
- RenderObject* renderer = node->renderer();
- if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer)
- continue;
-
- rendererList.append(renderer);
- repaintRect.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
- }
-
+ FloatRect repaintRect = m_maskBoundaries;
AffineTransform contextTransform;
// We need to scale repaintRect for objectBoundingBox to get the drawing area.
if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
@@ -180,9 +166,15 @@ void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGM
maskImageContext->concatCTM(contextTransform);
// draw the content into the ImageBuffer
- Vector<RenderObject*>::iterator end = rendererList.end();
- for (Vector<RenderObject*>::iterator it = rendererList.begin(); it != end; it++)
- renderSubtreeToImage(maskerData->maskImage.get(), *it);
+ for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
+ RenderObject* renderer = node->renderer();
+ if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer)
+ continue;
+ RenderStyle* style = renderer->style();
+ if (!style || style->display() == NONE || style->visibility() != VISIBLE)
+ continue;
+ renderSubtreeToImage(maskerData->maskImage.get(), renderer);
+ }
maskImageContext->restore();
@@ -205,4 +197,40 @@ void RenderSVGResourceMasker::createMaskImage(MaskerData* maskerData, const SVGM
maskerData->maskImage->putUnmultipliedImageData(imageData.get(), maskImageRect, IntPoint());
}
+void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
+{
+ for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
+ RenderObject* renderer = childNode->renderer();
+ if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ continue;
+ RenderStyle* style = renderer->style();
+ if (!style || style->display() == NONE || style->visibility() != VISIBLE)
+ continue;
+ m_maskBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates()));
+ }
}
+
+FloatRect RenderSVGResourceMasker::resourceBoundingBox(const FloatRect& objectBoundingBox)
+{
+ if (m_maskBoundaries.isEmpty())
+ calculateMaskContentRepaintRect();
+
+ SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
+ if (!maskElement)
+ return FloatRect();
+
+ FloatRect maskRect = m_maskBoundaries;
+ if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+ AffineTransform transform;
+ transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
+ transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
+ maskRect = transform.mapRect(maskRect);
+ }
+
+ maskRect.intersect(maskElement->maskBoundingBox(objectBoundingBox));
+ return maskRect;
+}
+
+}
+
+#endif // ENABLE(SVG)