summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/SVGResources.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/SVGResources.cpp')
-rw-r--r--WebCore/rendering/SVGResources.cpp360
1 files changed, 360 insertions, 0 deletions
diff --git a/WebCore/rendering/SVGResources.cpp b/WebCore/rendering/SVGResources.cpp
new file mode 100644
index 0000000..de23ce1
--- /dev/null
+++ b/WebCore/rendering/SVGResources.cpp
@@ -0,0 +1,360 @@
+/*
+ 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
+ aint 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"
+#include "SVGResources.h"
+
+#if ENABLE(SVG)
+#include "RenderSVGResourceClipper.h"
+#include "RenderSVGResourceFilter.h"
+#include "RenderSVGResourceMarker.h"
+#include "RenderSVGResourceMasker.h"
+#include "SVGPaint.h"
+#include "SVGRenderStyle.h"
+#include "SVGURIReference.h"
+
+namespace WebCore {
+
+SVGResources::SVGResources()
+ : m_clipper(0)
+#if ENABLE(FILTERS)
+ , m_filter(0)
+#endif
+ , m_markerStart(0)
+ , m_markerMid(0)
+ , m_markerEnd(0)
+ , m_masker(0)
+ , m_fill(0)
+ , m_stroke(0)
+{
+}
+
+static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, SVGPaint* paint, AtomicString& id, bool& hasPendingResource)
+{
+ ASSERT(paint);
+
+ SVGPaint::SVGPaintType paintType = paint->paintType();
+ if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
+ return 0;
+
+ id = SVGURIReference::getTarget(paint->uri());
+ if (RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id))
+ return container;
+
+ hasPendingResource = true;
+ return 0;
+}
+
+static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, Node* node)
+{
+ ASSERT(node);
+ if (!node->isSVGElement())
+ return;
+
+ SVGElement* svgElement = static_cast<SVGElement*>(node);
+ if (!svgElement->isStyled())
+ return;
+
+ extensions->addPendingResource(id, static_cast<SVGStyledElement*>(svgElement));
+}
+
+bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRenderStyle* style)
+{
+ ASSERT(object);
+ ASSERT(style);
+
+ Node* node = object->node();
+ ASSERT(node);
+
+ Document* document = object->document();
+ ASSERT(document);
+
+ SVGDocumentExtensions* extensions = document->accessSVGExtensions();
+ ASSERT(extensions);
+
+ bool foundResources = false;
+ if (style->hasClipper()) {
+ AtomicString id(style->clipperResource());
+ m_clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, id);
+ if (m_clipper)
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, node);
+ }
+
+ if (style->hasMasker()) {
+ AtomicString id(style->maskerResource());
+ m_masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, id);
+ if (m_masker)
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, node);
+ }
+
+#if ENABLE(FILTERS)
+ if (style->hasFilter()) {
+ AtomicString id(style->filterResource());
+ m_filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, id);
+ if (m_filter)
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, node);
+ }
+#endif
+
+ if (style->hasMarkers()) {
+ AtomicString markerStartId(style->markerStartResource());
+ m_markerStart = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId);
+ if (m_markerStart)
+ foundResources = true;
+ else
+ registerPendingResource(extensions, markerStartId, node);
+
+ AtomicString markerMidId(style->markerMidResource());
+ m_markerMid = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId);
+ if (m_markerMid)
+ foundResources = true;
+ else
+ registerPendingResource(extensions, markerMidId, node);
+
+ AtomicString markerEndId(style->markerEndResource());
+ m_markerEnd = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId);
+ if (m_markerEnd)
+ foundResources = true;
+ else
+ registerPendingResource(extensions, markerEndId, node);
+ }
+
+ if (style->hasFill()) {
+ bool hasPendingResource = false;
+ AtomicString id;
+ m_fill = paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource);
+ if (m_fill)
+ foundResources = true;
+ else if (hasPendingResource)
+ registerPendingResource(extensions, id, node);
+ }
+
+ if (style->hasStroke()) {
+ bool hasPendingResource = false;
+ AtomicString id;
+ m_stroke = paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource);
+ if (m_stroke)
+ foundResources = true;
+ else if (hasPendingResource)
+ registerPendingResource(extensions, id, node);
+ }
+
+ return foundResources;
+}
+
+void SVGResources::invalidateClient(RenderObject* object) const
+{
+ // Ordinary resources
+ if (m_clipper)
+ m_clipper->invalidateClient(object);
+#if ENABLE(FILTERS)
+ if (m_filter)
+ m_filter->invalidateClient(object);
+#endif
+ if (m_masker)
+ m_masker->invalidateClient(object);
+ if (m_markerStart)
+ m_markerStart->invalidateClient(object);
+ if (m_markerMid)
+ m_markerMid->invalidateClient(object);
+ if (m_markerEnd)
+ m_markerEnd->invalidateClient(object);
+
+ // Paint servers
+ if (m_fill)
+ m_fill->invalidateClient(object);
+ if (m_stroke)
+ m_stroke->invalidateClient(object);
+}
+
+void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
+{
+ ASSERT(resource);
+
+ switch (resource->resourceType()) {
+ case MaskerResourceType:
+ if (m_masker == resource) {
+ m_masker->invalidateClients();
+ m_masker = 0;
+ }
+ break;
+ case MarkerResourceType:
+ if (m_markerStart == resource) {
+ m_markerStart->invalidateClients();
+ m_markerStart = 0;
+ }
+
+ if (m_markerMid == resource) {
+ m_markerMid->invalidateClients();
+ m_markerMid = 0;
+ }
+
+ if (m_markerEnd == resource) {
+ m_markerEnd->invalidateClients();
+ m_markerEnd = 0;
+ }
+ break;
+ case PatternResourceType:
+ case LinearGradientResourceType:
+ case RadialGradientResourceType:
+ if (m_fill == resource) {
+ m_fill->invalidateClients();
+ m_fill = 0;
+ }
+
+ if (m_stroke == resource) {
+ m_stroke->invalidateClients();
+ m_stroke = 0;
+ }
+ break;
+#if ENABLE(FILTERS)
+ case FilterResourceType:
+ if (m_filter == resource) {
+ m_filter->invalidateClients();
+ m_filter = 0;
+ }
+ break;
+#endif
+ case ClipperResourceType:
+ if (m_clipper == resource) {
+ m_clipper->invalidateClients();
+ m_clipper = 0;
+ }
+ break;
+ case SolidColorResourceType:
+ ASSERT_NOT_REACHED();
+ }
+}
+
+void SVGResources::buildSetOfResources(HashSet<RenderSVGResourceContainer*>& set)
+{
+ // Ordinary resources
+ if (m_clipper)
+ set.add(m_clipper);
+#if ENABLE(FILTERS)
+ if (m_filter)
+ set.add(m_filter);
+#endif
+ if (m_markerStart)
+ set.add(m_markerStart);
+ if (m_markerMid)
+ set.add(m_markerMid);
+ if (m_markerEnd)
+ set.add(m_markerEnd);
+ if (m_masker)
+ set.add(m_masker);
+
+ // Paint servers
+ if (m_fill)
+ set.add(m_fill);
+ if (m_stroke)
+ set.add(m_stroke);
+}
+
+void SVGResources::resetClipper()
+{
+ ASSERT(m_clipper);
+ m_clipper = 0;
+}
+
+#if ENABLE(FILTERS)
+void SVGResources::resetFilter()
+{
+ ASSERT(m_filter);
+ m_filter = 0;
+}
+#endif
+
+void SVGResources::resetMarkerStart()
+{
+ ASSERT(m_markerStart);
+ m_markerStart = 0;
+}
+
+void SVGResources::resetMarkerMid()
+{
+ ASSERT(m_markerMid);
+ m_markerMid = 0;
+}
+
+void SVGResources::resetMarkerEnd()
+{
+ ASSERT(m_markerEnd);
+ m_markerEnd = 0;
+}
+
+void SVGResources::resetMasker()
+{
+ ASSERT(m_masker);
+ m_masker = 0;
+}
+
+void SVGResources::resetFill()
+{
+ ASSERT(m_fill);
+ m_fill = 0;
+}
+
+void SVGResources::resetStroke()
+{
+ ASSERT(m_stroke);
+ m_stroke = 0;
+}
+
+#ifndef NDEBUG
+void SVGResources::dump(const RenderObject* object)
+{
+ ASSERT(object);
+ ASSERT(object->node());
+
+ fprintf(stderr, "-> this=%p, SVGResources(renderer=%p, node=%p)\n", this, object, object->node());
+ fprintf(stderr, " | DOM Tree:\n");
+ object->node()->showTreeForThis();
+
+ fprintf(stderr, "\n | List of resources:\n");
+ if (m_clipper)
+ fprintf(stderr, " |-> Clipper : %p (node=%p)\n", m_clipper, m_clipper->node());
+#if ENABLE(FILTERS)
+ if (m_filter)
+ fprintf(stderr, " |-> Filter : %p (node=%p)\n", m_filter, m_filter->node());
+#endif
+ if (m_markerStart)
+ fprintf(stderr, " |-> MarkerStart: %p (node=%p)\n", m_markerStart, m_markerStart->node());
+ if (m_markerMid)
+ fprintf(stderr, " |-> MarkerMid : %p (node=%p)\n", m_markerMid, m_markerMid->node());
+ if (m_markerEnd)
+ fprintf(stderr, " |-> MarkerEnd : %p (node=%p)\n", m_markerEnd, m_markerEnd->node());
+ if (m_masker)
+ fprintf(stderr, " |-> Masker : %p (node=%p)\n", m_masker, m_masker->node());
+ if (m_fill)
+ fprintf(stderr, " |-> Fill : %p (node=%p)\n", m_fill, m_fill->node());
+ if (m_stroke)
+ fprintf(stderr, " |-> Stroke : %p (node=%p)\n", m_stroke, m_stroke->node());
+}
+#endif
+
+}
+
+#endif