diff options
author | Kristian Monsen <kristianm@google.com> | 2010-05-21 16:53:46 +0100 |
---|---|---|
committer | Kristian Monsen <kristianm@google.com> | 2010-05-25 10:24:15 +0100 |
commit | 6c2af9490927c3c5959b5cb07461b646f8b32f6c (patch) | |
tree | f7111b9b22befab472616c1d50ec94eb50f1ec8c /WebCore/rendering/RenderSVGResourceMasker.cpp | |
parent | a149172322a9067c14e8b474a53e63649aa17cad (diff) | |
download | external_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.cpp | 74 |
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) |