summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/rendering/RenderSVGResourceContainer.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /Source/WebCore/rendering/RenderSVGResourceContainer.cpp
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'Source/WebCore/rendering/RenderSVGResourceContainer.cpp')
-rw-r--r--Source/WebCore/rendering/RenderSVGResourceContainer.cpp193
1 files changed, 193 insertions, 0 deletions
diff --git a/Source/WebCore/rendering/RenderSVGResourceContainer.cpp b/Source/WebCore/rendering/RenderSVGResourceContainer.cpp
new file mode 100644
index 0000000..fb30efd
--- /dev/null
+++ b/Source/WebCore/rendering/RenderSVGResourceContainer.cpp
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "config.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceContainer.h"
+
+#include "RenderSVGShadowTreeRootContainer.h"
+#include "SVGStyledTransformableElement.h"
+
+namespace WebCore {
+
+static inline SVGDocumentExtensions* svgExtensionsFromNode(Node* node)
+{
+ ASSERT(node);
+ ASSERT(node->document());
+ return node->document()->accessSVGExtensions();
+}
+
+RenderSVGResourceContainer::RenderSVGResourceContainer(SVGStyledElement* node)
+ : RenderSVGHiddenContainer(node)
+ , m_id(node->hasID() ? node->getIdAttribute() : nullAtom)
+ , m_registered(false)
+{
+}
+
+RenderSVGResourceContainer::~RenderSVGResourceContainer()
+{
+ if (m_registered)
+ svgExtensionsFromNode(node())->removeResource(m_id);
+}
+
+void RenderSVGResourceContainer::layout()
+{
+ // Invalidate all resources if our layout changed.
+ if (m_everHadLayout && selfNeedsLayout())
+ removeAllClientsFromCache();
+
+ RenderSVGHiddenContainer::layout();
+}
+
+void RenderSVGResourceContainer::destroy()
+{
+ SVGResourcesCache::resourceDestroyed(this);
+ RenderSVGHiddenContainer::destroy();
+}
+
+void RenderSVGResourceContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderSVGHiddenContainer::styleDidChange(diff, oldStyle);
+
+ if (!m_registered) {
+ m_registered = true;
+ registerResource();
+ }
+}
+
+void RenderSVGResourceContainer::idChanged()
+{
+ // Invalidate all our current clients.
+ removeAllClientsFromCache();
+
+ // Remove old id, that is guaranteed to be present in cache.
+ SVGDocumentExtensions* extensions = svgExtensionsFromNode(node());
+ extensions->removeResource(m_id);
+ m_id = static_cast<Element*>(node())->getIdAttribute();
+
+ registerResource();
+}
+
+void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode mode)
+{
+ if (m_clients.isEmpty())
+ return;
+
+ bool needsLayout = mode == LayoutAndBoundariesInvalidation;
+ bool markForInvalidation = mode != ParentOnlyInvalidation;
+
+ HashSet<RenderObject*>::iterator end = m_clients.end();
+ for (HashSet<RenderObject*>::iterator it = m_clients.begin(); it != end; ++it) {
+ RenderObject* client = *it;
+ if (client->isSVGResourceContainer()) {
+ client->toRenderSVGResourceContainer()->removeAllClientsFromCache(markForInvalidation);
+ continue;
+ }
+
+ if (markForInvalidation)
+ markClientForInvalidation(client, mode);
+
+ if (needsLayout)
+ client->setNeedsLayout(true);
+
+ // Invalidate resources in ancestor chain, if needed.
+ RenderObject* current = client->parent();
+ while (current) {
+ if (current->isSVGResourceContainer()) {
+ current->toRenderSVGResourceContainer()->removeAllClientsFromCache(markForInvalidation);
+ break;
+ }
+
+ current = current->parent();
+ }
+ }
+}
+
+void RenderSVGResourceContainer::markClientForInvalidation(RenderObject* client, InvalidationMode mode)
+{
+ ASSERT(client);
+ ASSERT(!m_clients.isEmpty());
+
+ switch (mode) {
+ case LayoutAndBoundariesInvalidation:
+ case BoundariesInvalidation:
+ client->setNeedsBoundariesUpdate();
+ break;
+ case RepaintInvalidation:
+ if (client->view())
+ client->repaint();
+ break;
+ case ParentOnlyInvalidation:
+ break;
+ }
+}
+
+void RenderSVGResourceContainer::addClient(RenderObject* client)
+{
+ ASSERT(client);
+ m_clients.add(client);
+}
+
+void RenderSVGResourceContainer::removeClient(RenderObject* client)
+{
+ ASSERT(client);
+ m_clients.remove(client);
+}
+
+void RenderSVGResourceContainer::registerResource()
+{
+ SVGDocumentExtensions* extensions = svgExtensionsFromNode(node());
+ if (!extensions->isPendingResource(m_id)) {
+ extensions->addResource(m_id, this);
+ return;
+ }
+
+ OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions->removePendingResource(m_id));
+
+ // Cache us with the new id.
+ extensions->addResource(m_id, this);
+
+ // Update cached resources of pending clients.
+ const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
+ for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
+ RenderObject* renderer = (*it)->renderer();
+ if (!renderer)
+ continue;
+ SVGResourcesCache::clientUpdatedFromElement(renderer, renderer->style());
+ renderer->setNeedsLayout(true);
+ }
+}
+
+// FIXME: This does not belong here.
+AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
+{
+ if (!object->isSVGPath())
+ return resourceTransform;
+
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
+ AffineTransform transform = resourceTransform;
+ transform.multiply(element->getScreenCTM(SVGLocatable::DisallowStyleUpdate));
+ return transform;
+}
+
+}
+
+#endif