diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-09 14:16:12 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-02-09 14:16:12 +0100 |
| commit | 03e12282df9aa1e1fb05a8b90f1cfc2e08764cec (patch) | |
| tree | 52599cd0ab782b1768e23ad176f7618f98333cb6 /Source/WebCore/rendering/svg | |
| parent | cd44dc59cdfc39534aef4d417e9f3c412e3be139 (diff) | |
| download | qtwebkit-03e12282df9aa1e1fb05a8b90f1cfc2e08764cec.tar.gz | |
Imported WebKit commit e09a82039aa4273ab318b71122e92d8e5f233525 (http://svn.webkit.org/repository/webkit/trunk@107223)
Diffstat (limited to 'Source/WebCore/rendering/svg')
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()) { |
