summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/svg
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-09 14:16:12 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-09 14:16:12 +0100
commit03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (patch)
tree52599cd0ab782b1768e23ad176f7618f98333cb6 /Source/WebCore/rendering/svg
parentcd44dc59cdfc39534aef4d417e9f3c412e3be139 (diff)
downloadqtwebkit-03e12282df9aa1e1fb05a8b90f1cfc2e08764cec.tar.gz
Imported WebKit commit e09a82039aa4273ab318b71122e92d8e5f233525 (http://svn.webkit.org/repository/webkit/trunk@107223)
Diffstat (limited to 'Source/WebCore/rendering/svg')
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.cpp3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResource.cpp35
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResource.h3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.cpp1
-rwxr-xr-xSource/WebCore/rendering/svg/RenderSVGShape.cpp16
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp9
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.h11
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.cpp16
9 files changed, 72 insertions, 24 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
index cffa755b7..515565521 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
@@ -63,6 +63,9 @@ void RenderSVGContainer::layout()
// Allow RenderSVGTransformableContainer to update its transform.
bool updatedTransform = calculateLocalTransform();
+ // RenderSVGViewportContainer needs to set the 'layout size changed' flag.
+ determineIfLayoutSizeChanged();
+
SVGRenderSupport::layoutChildren(this, selfNeedsLayout() || SVGRenderSupport::filtersForceContainerLayout(this));
// Invalidate all resources of this client if our layout changed.
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.h b/Source/WebCore/rendering/svg/RenderSVGContainer.h
index 60b91e14c..c7d9f205f 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.h
@@ -67,6 +67,8 @@ protected:
virtual void applyViewportClip(PaintInfo&) { }
virtual bool pointIsInsideViewportClip(const FloatPoint& /*pointInParent*/) { return true; }
+ virtual void determineIfLayoutSizeChanged() { }
+
bool selfWillPaint();
void updateCachedBoundaries();
diff --git a/Source/WebCore/rendering/svg/RenderSVGResource.cpp b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
index 24adf5bf4..4fc5e2376 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResource.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
@@ -161,37 +161,42 @@ RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
return s_sharedSolidPaintingResource;
}
-void RenderSVGResource::removeFromFilterCache(RenderObject* object)
+static inline void removeFromFilterCacheAndInvalidateDependencies(RenderObject* object, bool needsLayout)
{
-#if ENABLE(FILTERS)
ASSERT(object);
-
- SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
- if (!resources)
+#if ENABLE(FILTERS)
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object)) {
+ if (RenderSVGResourceFilter* filter = resources->filter())
+ filter->removeClientFromCache(object);
+ }
+#endif
+ if (!object->node() || !object->node()->isSVGElement())
return;
-
- RenderSVGResourceFilter* filter = resources->filter();
- if (!filter)
+ HashSet<SVGElement*>* dependencies = object->document()->accessSVGExtensions()->setOfElementsReferencingTarget(static_cast<SVGElement*>(object->node()));
+ if (!dependencies)
return;
-
- filter->removeClientFromCache(object);
-#else
- UNUSED_PARAM(object);
-#endif
+ HashSet<SVGElement*>::iterator end = dependencies->end();
+ for (HashSet<SVGElement*>::iterator it = dependencies->begin(); it != end; ++it) {
+ if (RenderObject* renderer = (*it)->renderer())
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, needsLayout);
+ }
}
void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject* object, bool needsLayout)
{
ASSERT(object);
+ ASSERT(object->document());
+ ASSERT(object->node());
+
if (needsLayout)
object->setNeedsLayout(true);
- removeFromFilterCache(object);
+ removeFromFilterCacheAndInvalidateDependencies(object, needsLayout);
// Invalidate resources in ancestor chain, if needed.
RenderObject* current = object->parent();
while (current) {
- removeFromFilterCache(current);
+ removeFromFilterCacheAndInvalidateDependencies(current, needsLayout);
if (current->isSVGResourceContainer()) {
// This will process the rest of the ancestors.
diff --git a/Source/WebCore/rendering/svg/RenderSVGResource.h b/Source/WebCore/rendering/svg/RenderSVGResource.h
index 8ff552bb1..e02015410 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResource.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResource.h
@@ -82,9 +82,6 @@ public:
static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
static void markForLayoutAndParentResourceInvalidation(RenderObject*, bool needsLayout = true);
-
-private:
- static void removeFromFilterCache(RenderObject*);
};
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
index 507f38324..ba821cca2 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
@@ -214,7 +214,6 @@ void RenderSVGRoot::layout()
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
m_isLayoutSizeChanged = needsLayout || (svg->hasRelativeLengths() && oldSize != size());
SVGRenderSupport::layoutChildren(this, needsLayout || SVGRenderSupport::filtersForceContainerLayout(this));
- m_isLayoutSizeChanged = false;
// At this point LayoutRepainter already grabbed the old bounds,
// recalculate them now so repaintAfterLayout() uses the new bounds.
diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.cpp b/Source/WebCore/rendering/svg/RenderSVGShape.cpp
index 136a53cf9..31f15251b 100755
--- a/Source/WebCore/rendering/svg/RenderSVGShape.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGShape.cpp
@@ -136,13 +136,21 @@ bool RenderSVGShape::strokeContains(const FloatPoint& point, bool requiresStroke
if (requiresStroke && !RenderSVGResource::strokePaintingResource(this, style(), fallbackColor))
return false;
- // FIXME: This is not correct for round linecaps. https://bugs.webkit.org/show_bug.cgi?id=76931
+ const SVGRenderStyle* svgStyle = style()->svgStyle();
for (size_t i = 0; i < m_zeroLengthLinecapLocations.size(); ++i) {
- if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], this->strokeWidth()).contains(point))
- return true;
+ ASSERT(style()->svgStyle()->hasStroke());
+ float strokeWidth = this->strokeWidth();
+ if (style()->svgStyle()->capStyle() == SquareCap) {
+ if (zeroLengthSubpathRect(m_zeroLengthLinecapLocations[i], strokeWidth).contains(point))
+ return true;
+ } else {
+ ASSERT(style()->svgStyle()->capStyle() == RoundCap);
+ FloatPoint radiusVector(point.x() - m_zeroLengthLinecapLocations[i].x(), point.y() - m_zeroLengthLinecapLocations[i].y());
+ if (radiusVector.lengthSquared() < strokeWidth * strokeWidth * .25f)
+ return true;
+ }
}
- const SVGRenderStyle* svgStyle = style()->svgStyle();
if (!svgStyle->strokeDashArray().isEmpty() || svgStyle->strokeMiterLimit() != svgStyle->initialStrokeMiterLimit()
|| svgStyle->joinStyle() != svgStyle->initialJoinStyle() || svgStyle->capStyle() != svgStyle->initialCapStyle() || static_cast<SVGElement*>(node())->isStyled()) {
if (!m_path)
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
index 8b7e65b65..1021aff00 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
@@ -34,9 +34,18 @@ namespace WebCore {
RenderSVGViewportContainer::RenderSVGViewportContainer(SVGStyledElement* node)
: RenderSVGContainer(node)
+ , m_isLayoutSizeChanged(false)
{
}
+void RenderSVGViewportContainer::determineIfLayoutSizeChanged()
+{
+ if (!node()->hasTagName(SVGNames::svgTag))
+ return;
+
+ m_isLayoutSizeChanged = static_cast<SVGSVGElement*>(node())->hasRelativeLengths() && selfNeedsLayout();
+}
+
void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
{
if (SVGRenderSupport::isOverflowHidden(this))
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
index 07be7eb9a..808d6727b 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
@@ -35,6 +35,10 @@ public:
explicit RenderSVGViewportContainer(SVGStyledElement*);
FloatRect viewport() const { return m_viewport; }
+ bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
+
+ virtual void determineIfLayoutSizeChanged();
+
private:
virtual bool isSVGContainer() const { return true; }
virtual bool isSVGViewportContainer() const { return true; }
@@ -50,6 +54,7 @@ private:
FloatRect m_viewport;
mutable AffineTransform m_localToParentTransform;
+ bool m_isLayoutSizeChanged : 1;
};
inline RenderSVGViewportContainer* toRenderSVGViewportContainer(RenderObject* object)
@@ -58,6 +63,12 @@ inline RenderSVGViewportContainer* toRenderSVGViewportContainer(RenderObject* ob
return static_cast<RenderSVGViewportContainer*>(object);
}
+inline const RenderSVGViewportContainer* toRenderSVGViewportContainer(const RenderObject* object)
+{
+ ASSERT(!object || !strcmp(object->renderName(), "RenderSVGViewportContainer"));
+ return static_cast<const RenderSVGViewportContainer*>(object);
+}
+
// This will catch anyone doing an unnecessary cast.
void toRenderSVGViewportContainer(const RenderSVGViewportContainer*);
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
index 2a3801bb2..6457ac006 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
@@ -39,6 +39,7 @@
#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
#include "RenderSVGRoot.h"
+#include "RenderSVGViewportContainer.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
#include "SVGStyledElement.h"
@@ -231,9 +232,22 @@ static inline void invalidateResourcesOfChildren(RenderObject* start)
invalidateResourcesOfChildren(child);
}
+static inline bool layoutSizeOfNearestViewportChanged(const RenderObject* start)
+{
+ while (start && !start->isSVGRoot() && !start->isSVGViewportContainer())
+ start = start->parent();
+
+ ASSERT(start);
+ ASSERT(start->isSVGRoot() || start->isSVGViewportContainer());
+ if (start->isSVGViewportContainer())
+ return toRenderSVGViewportContainer(start)->isLayoutSizeChanged();
+
+ return toRenderSVGRoot(start)->isLayoutSizeChanged();
+}
+
void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
{
- bool layoutSizeChanged = findTreeRootObject(start)->isLayoutSizeChanged();
+ bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {