[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
zimmermann at webkit.org
zimmermann at webkit.org
Wed Dec 22 11:35:58 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 1c4cfe69713fc1f33cc7c00a8ed4172abc2c6810
Author: zimmermann at webkit.org <zimmermann at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Jul 30 11:02:46 2010 +0000
2010-07-30 Nikolas Zimmermann <nzimmermann at rim.com>
Reviewed by Dirk Schulze.
Optimize SVGResources memory usage
https://bugs.webkit.org/show_bug.cgi?id=43236
Instead of storing pointers to all possible resources that could be applied to an element, group them in three categories:
clipper/filter/masker, marker-start/marker-mid/marker-end, and fill/stroke.
Only build the cached resources data for elements where the properties can be applied to. Maintain a static list of tagnames
for each of the three categories, to avoid doing unncessary work.
Doesn't affect any tests.
* rendering/SVGResources.cpp:
(WebCore::SVGResources::SVGResources):
(WebCore::clipperFilterMaskerTags):
(WebCore::markerTags):
(WebCore::fillAndStrokeTags):
(WebCore::SVGResources::buildCachedResources):
(WebCore::SVGResources::invalidateClient):
(WebCore::SVGResources::resourceDestroyed):
(WebCore::SVGResources::buildSetOfResources):
(WebCore::SVGResources::setClipper):
(WebCore::SVGResources::resetClipper):
(WebCore::SVGResources::setFilter):
(WebCore::SVGResources::resetFilter):
(WebCore::SVGResources::setMarkerStart):
(WebCore::SVGResources::resetMarkerStart):
(WebCore::SVGResources::setMarkerMid):
(WebCore::SVGResources::resetMarkerMid):
(WebCore::SVGResources::setMarkerEnd):
(WebCore::SVGResources::resetMarkerEnd):
(WebCore::SVGResources::setMasker):
(WebCore::SVGResources::resetMasker):
(WebCore::SVGResources::setFill):
(WebCore::SVGResources::resetFill):
(WebCore::SVGResources::setStroke):
(WebCore::SVGResources::resetStroke):
(WebCore::SVGResources::dump):
* rendering/SVGResources.h:
(WebCore::SVGResources::clipper):
(WebCore::SVGResources::filter):
(WebCore::SVGResources::markerStart):
(WebCore::SVGResources::markerMid):
(WebCore::SVGResources::markerEnd):
(WebCore::SVGResources::masker):
(WebCore::SVGResources::fill):
(WebCore::SVGResources::stroke):
(WebCore::SVGResources::ClipperFilterMaskerData::ClipperFilterMaskerData):
(WebCore::SVGResources::ClipperFilterMaskerData::create):
(WebCore::SVGResources::MarkerData::MarkerData):
(WebCore::SVGResources::MarkerData::create):
(WebCore::SVGResources::FillStrokeData::FillStrokeData):
(WebCore::SVGResources::FillStrokeData::create):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@64345 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index e7e067f..8313409 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,60 @@
+2010-07-30 Nikolas Zimmermann <nzimmermann at rim.com>
+
+ Reviewed by Dirk Schulze.
+
+ Optimize SVGResources memory usage
+ https://bugs.webkit.org/show_bug.cgi?id=43236
+
+ Instead of storing pointers to all possible resources that could be applied to an element, group them in three categories:
+ clipper/filter/masker, marker-start/marker-mid/marker-end, and fill/stroke.
+
+ Only build the cached resources data for elements where the properties can be applied to. Maintain a static list of tagnames
+ for each of the three categories, to avoid doing unncessary work.
+
+ Doesn't affect any tests.
+
+ * rendering/SVGResources.cpp:
+ (WebCore::SVGResources::SVGResources):
+ (WebCore::clipperFilterMaskerTags):
+ (WebCore::markerTags):
+ (WebCore::fillAndStrokeTags):
+ (WebCore::SVGResources::buildCachedResources):
+ (WebCore::SVGResources::invalidateClient):
+ (WebCore::SVGResources::resourceDestroyed):
+ (WebCore::SVGResources::buildSetOfResources):
+ (WebCore::SVGResources::setClipper):
+ (WebCore::SVGResources::resetClipper):
+ (WebCore::SVGResources::setFilter):
+ (WebCore::SVGResources::resetFilter):
+ (WebCore::SVGResources::setMarkerStart):
+ (WebCore::SVGResources::resetMarkerStart):
+ (WebCore::SVGResources::setMarkerMid):
+ (WebCore::SVGResources::resetMarkerMid):
+ (WebCore::SVGResources::setMarkerEnd):
+ (WebCore::SVGResources::resetMarkerEnd):
+ (WebCore::SVGResources::setMasker):
+ (WebCore::SVGResources::resetMasker):
+ (WebCore::SVGResources::setFill):
+ (WebCore::SVGResources::resetFill):
+ (WebCore::SVGResources::setStroke):
+ (WebCore::SVGResources::resetStroke):
+ (WebCore::SVGResources::dump):
+ * rendering/SVGResources.h:
+ (WebCore::SVGResources::clipper):
+ (WebCore::SVGResources::filter):
+ (WebCore::SVGResources::markerStart):
+ (WebCore::SVGResources::markerMid):
+ (WebCore::SVGResources::markerEnd):
+ (WebCore::SVGResources::masker):
+ (WebCore::SVGResources::fill):
+ (WebCore::SVGResources::stroke):
+ (WebCore::SVGResources::ClipperFilterMaskerData::ClipperFilterMaskerData):
+ (WebCore::SVGResources::ClipperFilterMaskerData::create):
+ (WebCore::SVGResources::MarkerData::MarkerData):
+ (WebCore::SVGResources::MarkerData::create):
+ (WebCore::SVGResources::FillStrokeData::FillStrokeData):
+ (WebCore::SVGResources::FillStrokeData::create):
+
2010-07-26 Andrei Popescu <andreip at google.com>
Reviewed by Jeremy Orlow.
diff --git a/WebCore/rendering/SVGResources.cpp b/WebCore/rendering/SVGResources.cpp
index de23ce1..b6ec75a 100644
--- a/WebCore/rendering/SVGResources.cpp
+++ b/WebCore/rendering/SVGResources.cpp
@@ -32,17 +32,89 @@
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)
+ : m_clipperFilterMaskerData(0)
+ , m_markerData(0)
+ , m_fillStrokeData(0)
+{
+}
+
+static HashSet<AtomicStringImpl*>& clipperFilterMaskerTags()
+{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+ if (s_tagList.isEmpty()) {
+ // "container elements": http://www.w3.org/TR/SVG11/intro.html#TermContainerElement
+ // "graphics elements" : http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement
+ s_tagList.add(SVGNames::aTag.localName().impl());
+ s_tagList.add(SVGNames::circleTag.localName().impl());
+ s_tagList.add(SVGNames::ellipseTag.localName().impl());
+ s_tagList.add(SVGNames::glyphTag.localName().impl());
+ s_tagList.add(SVGNames::gTag.localName().impl());
+ s_tagList.add(SVGNames::imageTag.localName().impl());
+ s_tagList.add(SVGNames::lineTag.localName().impl());
+ s_tagList.add(SVGNames::markerTag.localName().impl());
+ s_tagList.add(SVGNames::maskTag.localName().impl());
+ s_tagList.add(SVGNames::missing_glyphTag.localName().impl());
+ s_tagList.add(SVGNames::pathTag.localName().impl());
+ s_tagList.add(SVGNames::polygonTag.localName().impl());
+ s_tagList.add(SVGNames::polylineTag.localName().impl());
+ s_tagList.add(SVGNames::rectTag.localName().impl());
+ s_tagList.add(SVGNames::svgTag.localName().impl());
+ s_tagList.add(SVGNames::textTag.localName().impl());
+ s_tagList.add(SVGNames::useTag.localName().impl());
+
+ // Not listed in the definitions is the clipPath element, the SVG spec says though:
+ // The "clipPath" element or any of its children can specify property "clip-path".
+ // So we have to add clipPathTag here, otherwhise clip-path on clipPath will fail.
+ // (Already mailed SVG WG, waiting for a solution)
+ s_tagList.add(SVGNames::clipPathTag.localName().impl());
+
+ // Not listed in the definitions are the text content elements, though filter/clipper/masker on tspan/text/.. is allowed.
+ // (Already mailed SVG WG, waiting for a solution)
+ s_tagList.add(SVGNames::altGlyphTag.localName().impl());
+ s_tagList.add(SVGNames::textPathTag.localName().impl());
+ s_tagList.add(SVGNames::trefTag.localName().impl());
+ s_tagList.add(SVGNames::tspanTag.localName().impl());
+
+ // Elements that we ignore, as it doesn't make any sense.
+ // defs, pattern, switch (FIXME: Mail SVG WG about these)
+ // symbol (is converted to a svg element, when referenced by use, we can safely ignore it.)
+ }
+
+ return s_tagList;
+}
+
+static HashSet<AtomicStringImpl*>& markerTags()
+{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+ if (s_tagList.isEmpty()) {
+ s_tagList.add(SVGNames::lineTag.localName().impl());
+ s_tagList.add(SVGNames::pathTag.localName().impl());
+ s_tagList.add(SVGNames::polygonTag.localName().impl());
+ s_tagList.add(SVGNames::polylineTag.localName().impl());
+ }
+
+ return s_tagList;
+}
+
+static HashSet<AtomicStringImpl*>& fillAndStrokeTags()
{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+ if (s_tagList.isEmpty()) {
+ s_tagList.add(SVGNames::altGlyphTag.localName().impl());
+ s_tagList.add(SVGNames::circleTag.localName().impl());
+ s_tagList.add(SVGNames::ellipseTag.localName().impl());
+ s_tagList.add(SVGNames::lineTag.localName().impl());
+ s_tagList.add(SVGNames::pathTag.localName().impl());
+ s_tagList.add(SVGNames::polygonTag.localName().impl());
+ s_tagList.add(SVGNames::polylineTag.localName().impl());
+ s_tagList.add(SVGNames::rectTag.localName().impl());
+ s_tagList.add(SVGNames::textTag.localName().impl());
+ s_tagList.add(SVGNames::textPathTag.localName().impl());
+ s_tagList.add(SVGNames::trefTag.localName().impl());
+ s_tagList.add(SVGNames::tspanTag.localName().impl());
+ }
+
+ return s_tagList;
}
static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, SVGPaint* paint, AtomicString& id, bool& hasPendingResource)
@@ -81,6 +153,7 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
Node* node = object->node();
ASSERT(node);
+ ASSERT(node->isElementNode());
Document* document = object->document();
ASSERT(document);
@@ -88,77 +161,77 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
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);
- }
+ AtomicStringImpl* tagNameImpl = static_cast<Element*>(node)->tagQName().localName().impl();
+ if (!tagNameImpl)
+ return false;
- if (style->hasMasker()) {
- AtomicString id(style->maskerResource());
- m_masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, id);
- if (m_masker)
- foundResources = true;
- else
- registerPendingResource(extensions, id, node);
- }
+ bool foundResources = false;
+ if (clipperFilterMaskerTags().contains(tagNameImpl)) {
+ if (style->hasClipper()) {
+ AtomicString id(style->clipperResource());
+ if (setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(document, id)))
+ 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);
- }
+ if (style->hasFilter()) {
+ AtomicString id(style->filterResource());
+ if (setFilter(getRenderSVGResourceById<RenderSVGResourceFilter>(document, id)))
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, node);
+ }
#endif
- if (style->hasMarkers()) {
+ if (style->hasMasker()) {
+ AtomicString id(style->maskerResource());
+ if (setMasker(getRenderSVGResourceById<RenderSVGResourceMasker>(document, id)))
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, node);
+ }
+ }
+
+ if (markerTags().contains(tagNameImpl) && style->hasMarkers()) {
AtomicString markerStartId(style->markerStartResource());
- m_markerStart = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId);
- if (m_markerStart)
+ if (setMarkerStart(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId)))
foundResources = true;
else
registerPendingResource(extensions, markerStartId, node);
AtomicString markerMidId(style->markerMidResource());
- m_markerMid = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId);
- if (m_markerMid)
+ if (setMarkerMid(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId)))
foundResources = true;
else
registerPendingResource(extensions, markerMidId, node);
AtomicString markerEndId(style->markerEndResource());
- m_markerEnd = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId);
- if (m_markerEnd)
+ if (setMarkerEnd(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId)))
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 (fillAndStrokeTags().contains(tagNameImpl)) {
+ if (style->hasFill()) {
+ bool hasPendingResource = false;
+ AtomicString id;
+ if (setFill(paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource)))
+ 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);
+ if (style->hasStroke()) {
+ bool hasPendingResource = false;
+ AtomicString id;
+ if (setStroke(paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource)))
+ foundResources = true;
+ else if (hasPendingResource)
+ registerPendingResource(extensions, id, node);
+ }
}
return foundResources;
@@ -166,81 +239,98 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
void SVGResources::invalidateClient(RenderObject* object) const
{
- // Ordinary resources
- if (m_clipper)
- m_clipper->invalidateClient(object);
+ if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData)
+ return;
+
+ if (m_clipperFilterMaskerData) {
+ if (m_clipperFilterMaskerData->clipper)
+ m_clipperFilterMaskerData->clipper->invalidateClient(object);
#if ENABLE(FILTERS)
- if (m_filter)
- m_filter->invalidateClient(object);
+ if (m_clipperFilterMaskerData->filter)
+ m_clipperFilterMaskerData->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);
+ if (m_clipperFilterMaskerData->masker)
+ m_clipperFilterMaskerData->masker->invalidateClient(object);
+ }
+
+ if (m_markerData) {
+ if (m_markerData->markerStart)
+ m_markerData->markerStart->invalidateClient(object);
+ if (m_markerData->markerMid)
+ m_markerData->markerMid->invalidateClient(object);
+ if (m_markerData->markerEnd)
+ m_markerData->markerEnd->invalidateClient(object);
+ }
+
+ if (m_fillStrokeData) {
+ if (m_fillStrokeData->fill)
+ m_fillStrokeData->fill->invalidateClient(object);
+ if (m_fillStrokeData->stroke)
+ m_fillStrokeData->stroke->invalidateClient(object);
+ }
}
void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
{
ASSERT(resource);
+ if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData)
+ return;
switch (resource->resourceType()) {
case MaskerResourceType:
- if (m_masker == resource) {
- m_masker->invalidateClients();
- m_masker = 0;
+ if (!m_clipperFilterMaskerData)
+ break;
+ if (m_clipperFilterMaskerData->masker == resource) {
+ m_clipperFilterMaskerData->masker->invalidateClients();
+ m_clipperFilterMaskerData->masker = 0;
}
break;
case MarkerResourceType:
- if (m_markerStart == resource) {
- m_markerStart->invalidateClients();
- m_markerStart = 0;
+ if (!m_markerData)
+ break;
+ if (m_markerData->markerStart == resource) {
+ m_markerData->markerStart->invalidateClients();
+ m_markerData->markerStart = 0;
}
-
- if (m_markerMid == resource) {
- m_markerMid->invalidateClients();
- m_markerMid = 0;
+ if (m_markerData->markerMid == resource) {
+ m_markerData->markerMid->invalidateClients();
+ m_markerData->markerMid = 0;
}
-
- if (m_markerEnd == resource) {
- m_markerEnd->invalidateClients();
- m_markerEnd = 0;
+ if (m_markerData->markerEnd == resource) {
+ m_markerData->markerEnd->invalidateClients();
+ m_markerData->markerEnd = 0;
}
break;
case PatternResourceType:
case LinearGradientResourceType:
case RadialGradientResourceType:
- if (m_fill == resource) {
- m_fill->invalidateClients();
- m_fill = 0;
+ if (!m_fillStrokeData)
+ break;
+ if (m_fillStrokeData->fill == resource) {
+ m_fillStrokeData->fill->invalidateClients();
+ m_fillStrokeData->fill = 0;
}
-
- if (m_stroke == resource) {
- m_stroke->invalidateClients();
- m_stroke = 0;
+ if (m_fillStrokeData->stroke == resource) {
+ m_fillStrokeData->stroke->invalidateClients();
+ m_fillStrokeData->stroke = 0;
}
break;
#if ENABLE(FILTERS)
case FilterResourceType:
- if (m_filter == resource) {
- m_filter->invalidateClients();
- m_filter = 0;
+ if (!m_clipperFilterMaskerData)
+ break;
+ if (m_clipperFilterMaskerData->filter == resource) {
+ m_clipperFilterMaskerData->filter->invalidateClients();
+ m_clipperFilterMaskerData->filter = 0;
}
break;
#endif
case ClipperResourceType:
- if (m_clipper == resource) {
- m_clipper->invalidateClients();
- m_clipper = 0;
+ if (!m_clipperFilterMaskerData)
+ break;
+ if (m_clipperFilterMaskerData->clipper == resource) {
+ m_clipperFilterMaskerData->clipper->invalidateClients();
+ m_clipperFilterMaskerData->clipper = 0;
}
break;
case SolidColorResourceType:
@@ -250,77 +340,189 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
void SVGResources::buildSetOfResources(HashSet<RenderSVGResourceContainer*>& set)
{
- // Ordinary resources
- if (m_clipper)
- set.add(m_clipper);
+ if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData)
+ return;
+
+ if (m_clipperFilterMaskerData) {
+ if (m_clipperFilterMaskerData->clipper)
+ set.add(m_clipperFilterMaskerData->clipper);
#if ENABLE(FILTERS)
- if (m_filter)
- set.add(m_filter);
+ if (m_clipperFilterMaskerData->filter)
+ set.add(m_clipperFilterMaskerData->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);
+ if (m_clipperFilterMaskerData->masker)
+ set.add(m_clipperFilterMaskerData->masker);
+ }
+
+ if (m_markerData) {
+ if (m_markerData->markerStart)
+ set.add(m_markerData->markerStart);
+ if (m_markerData->markerMid)
+ set.add(m_markerData->markerMid);
+ if (m_markerData->markerEnd)
+ set.add(m_markerData->markerEnd);
+ }
+
+ if (m_fillStrokeData) {
+ if (m_fillStrokeData->fill)
+ set.add(m_fillStrokeData->fill);
+ if (m_fillStrokeData->stroke)
+ set.add(m_fillStrokeData->stroke);
+ }
+}
+
+bool SVGResources::setClipper(RenderSVGResourceClipper* clipper)
+{
+ if (!clipper)
+ return false;
+
+ if (!m_clipperFilterMaskerData)
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+ m_clipperFilterMaskerData->clipper = clipper;
+ return true;
}
void SVGResources::resetClipper()
{
- ASSERT(m_clipper);
- m_clipper = 0;
+ ASSERT(m_clipperFilterMaskerData);
+ ASSERT(m_clipperFilterMaskerData->clipper);
+ m_clipperFilterMaskerData->clipper = 0;
}
#if ENABLE(FILTERS)
+bool SVGResources::setFilter(RenderSVGResourceFilter* filter)
+{
+ if (!filter)
+ return false;
+
+ if (!m_clipperFilterMaskerData)
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+ m_clipperFilterMaskerData->filter = filter;
+ return true;
+}
+
void SVGResources::resetFilter()
{
- ASSERT(m_filter);
- m_filter = 0;
+ ASSERT(m_clipperFilterMaskerData);
+ ASSERT(m_clipperFilterMaskerData->filter);
+ m_clipperFilterMaskerData->filter = 0;
}
#endif
+bool SVGResources::setMarkerStart(RenderSVGResourceMarker* markerStart)
+{
+ if (!markerStart)
+ return false;
+
+ if (!m_markerData)
+ m_markerData = MarkerData::create();
+
+ m_markerData->markerStart = markerStart;
+ return true;
+}
+
void SVGResources::resetMarkerStart()
{
- ASSERT(m_markerStart);
- m_markerStart = 0;
+ ASSERT(m_markerData);
+ ASSERT(m_markerData->markerStart);
+ m_markerData->markerStart = 0;
+}
+
+bool SVGResources::setMarkerMid(RenderSVGResourceMarker* markerMid)
+{
+ if (!markerMid)
+ return false;
+
+ if (!m_markerData)
+ m_markerData = MarkerData::create();
+
+ m_markerData->markerMid = markerMid;
+ return true;
}
void SVGResources::resetMarkerMid()
{
- ASSERT(m_markerMid);
- m_markerMid = 0;
+ ASSERT(m_markerData);
+ ASSERT(m_markerData->markerMid);
+ m_markerData->markerMid = 0;
+}
+
+bool SVGResources::setMarkerEnd(RenderSVGResourceMarker* markerEnd)
+{
+ if (!markerEnd)
+ return false;
+
+ if (!m_markerData)
+ m_markerData = MarkerData::create();
+
+ m_markerData->markerEnd = markerEnd;
+ return true;
}
void SVGResources::resetMarkerEnd()
{
- ASSERT(m_markerEnd);
- m_markerEnd = 0;
+ ASSERT(m_markerData);
+ ASSERT(m_markerData->markerEnd);
+ m_markerData->markerEnd = 0;
+}
+
+bool SVGResources::setMasker(RenderSVGResourceMasker* masker)
+{
+ if (!masker)
+ return false;
+
+ if (!m_clipperFilterMaskerData)
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+ m_clipperFilterMaskerData->masker = masker;
+ return true;
}
void SVGResources::resetMasker()
{
- ASSERT(m_masker);
- m_masker = 0;
+ ASSERT(m_clipperFilterMaskerData);
+ ASSERT(m_clipperFilterMaskerData->masker);
+ m_clipperFilterMaskerData->masker = 0;
+}
+
+bool SVGResources::setFill(RenderSVGResourceContainer* fill)
+{
+ if (!fill)
+ return false;
+
+ if (!m_fillStrokeData)
+ m_fillStrokeData = FillStrokeData::create();
+
+ m_fillStrokeData->fill = fill;
+ return true;
}
void SVGResources::resetFill()
{
- ASSERT(m_fill);
- m_fill = 0;
+ ASSERT(m_fillStrokeData);
+ ASSERT(m_fillStrokeData->fill);
+ m_fillStrokeData->fill = 0;
+}
+
+bool SVGResources::setStroke(RenderSVGResourceContainer* stroke)
+{
+ if (!stroke)
+ return false;
+
+ if (!m_fillStrokeData)
+ m_fillStrokeData = FillStrokeData::create();
+
+ m_fillStrokeData->stroke = stroke;
+ return true;
}
void SVGResources::resetStroke()
{
- ASSERT(m_stroke);
- m_stroke = 0;
+ ASSERT(m_fillStrokeData);
+ ASSERT(m_fillStrokeData->stroke);
+ m_fillStrokeData->stroke = 0;
}
#ifndef NDEBUG
@@ -334,24 +536,32 @@ void SVGResources::dump(const RenderObject* object)
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 (m_clipperFilterMaskerData) {
+ if (RenderSVGResourceClipper* clipper = m_clipperFilterMaskerData->clipper)
+ fprintf(stderr, " |-> Clipper : %p (node=%p)\n", clipper, clipper->node());
#if ENABLE(FILTERS)
- if (m_filter)
- fprintf(stderr, " |-> Filter : %p (node=%p)\n", m_filter, m_filter->node());
+ if (RenderSVGResourceFilter* filter = m_clipperFilterMaskerData->filter)
+ fprintf(stderr, " |-> Filter : %p (node=%p)\n", filter, 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());
+ if (RenderSVGResourceMasker* masker = m_clipperFilterMaskerData->masker)
+ fprintf(stderr, " |-> Masker : %p (node=%p)\n", masker, masker->node());
+ }
+
+ if (m_markerData) {
+ if (RenderSVGResourceMarker* markerStart = m_markerData->markerStart)
+ fprintf(stderr, " |-> MarkerStart: %p (node=%p)\n", markerStart, markerStart->node());
+ if (RenderSVGResourceMarker* markerMid = m_markerData->markerMid)
+ fprintf(stderr, " |-> MarkerMid : %p (node=%p)\n", markerMid, markerMid->node());
+ if (RenderSVGResourceMarker* markerEnd = m_markerData->markerEnd)
+ fprintf(stderr, " |-> MarkerEnd : %p (node=%p)\n", markerEnd, markerEnd->node());
+ }
+
+ if (m_fillStrokeData) {
+ if (RenderSVGResourceContainer* fill = m_fillStrokeData->fill)
+ fprintf(stderr, " |-> Fill : %p (node=%p)\n", fill, fill->node());
+ if (RenderSVGResourceContainer* stroke = m_fillStrokeData->stroke)
+ fprintf(stderr, " |-> Stroke : %p (node=%p)\n", stroke, stroke->node());
+ }
}
#endif
diff --git a/WebCore/rendering/SVGResources.h b/WebCore/rendering/SVGResources.h
index 57a4140..0486758 100644
--- a/WebCore/rendering/SVGResources.h
+++ b/WebCore/rendering/SVGResources.h
@@ -23,6 +23,8 @@
#if ENABLE(SVG)
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -43,18 +45,18 @@ public:
bool buildCachedResources(const RenderObject*, const SVGRenderStyle*);
// Ordinary resources
- RenderSVGResourceClipper* clipper() const { return m_clipper; }
+ RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
#if ENABLE(FILTERS)
- RenderSVGResourceFilter* filter() const { return m_filter; }
+ RenderSVGResourceFilter* filter() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->filter : 0; }
#endif
- RenderSVGResourceMarker* markerStart() const { return m_markerStart; }
- RenderSVGResourceMarker* markerMid() const { return m_markerMid; }
- RenderSVGResourceMarker* markerEnd() const { return m_markerEnd; }
- RenderSVGResourceMasker* masker() const { return m_masker; }
+ RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
+ RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
+ RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
+ RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
// Paint servers
- RenderSVGResourceContainer* fill() const { return m_fill; }
- RenderSVGResourceContainer* stroke() const { return m_stroke; }
+ RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
+ RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
@@ -82,19 +84,87 @@ private:
void resetStroke();
private:
- // Ordinary resources
- RenderSVGResourceClipper* m_clipper;
+ bool setClipper(RenderSVGResourceClipper*);
+#if ENABLE(FILTERS)
+ bool setFilter(RenderSVGResourceFilter*);
+#endif
+ bool setMarkerStart(RenderSVGResourceMarker*);
+ bool setMarkerMid(RenderSVGResourceMarker*);
+ bool setMarkerEnd(RenderSVGResourceMarker*);
+ bool setMasker(RenderSVGResourceMasker*);
+ bool setFill(RenderSVGResourceContainer*);
+ bool setStroke(RenderSVGResourceContainer*);
+
+ // From SVG 1.1 2nd Edition
+ // clipper: 'container elements' and 'graphics elements'
+ // filter: 'container elements' and 'graphics elements'
+ // masker: 'container elements' and 'graphics elements'
+ // -> a, circle, defs, ellipse, glyph, g, image, line, marker, mask, missing-glyph, path, pattern, polygon, polyline, rect, svg, switch, symbol, text, use
+ struct ClipperFilterMaskerData {
+ ClipperFilterMaskerData()
+ : clipper(0)
#if ENABLE(FILTERS)
- RenderSVGResourceFilter* m_filter;
+ , filter(0)
#endif
- RenderSVGResourceMarker* m_markerStart;
- RenderSVGResourceMarker* m_markerMid;
- RenderSVGResourceMarker* m_markerEnd;
- RenderSVGResourceMasker* m_masker;
+ , masker(0)
+ {
+ }
- // Paint servers
- RenderSVGResourceContainer* m_fill;
- RenderSVGResourceContainer* m_stroke;
+ static PassOwnPtr<ClipperFilterMaskerData> create()
+ {
+ return new ClipperFilterMaskerData;
+ }
+
+ RenderSVGResourceClipper* clipper;
+#if ENABLE(FILTERS)
+ RenderSVGResourceFilter* filter;
+#endif
+ RenderSVGResourceMasker* masker;
+ };
+
+ // From SVG 1.1 2nd Edition
+ // marker: line, path, polygon, polyline
+ struct MarkerData {
+ MarkerData()
+ : markerStart(0)
+ , markerMid(0)
+ , markerEnd(0)
+ {
+ }
+
+ static PassOwnPtr<MarkerData> create()
+ {
+ return new MarkerData;
+ }
+
+ RenderSVGResourceMarker* markerStart;
+ RenderSVGResourceMarker* markerMid;
+ RenderSVGResourceMarker* markerEnd;
+ };
+
+ // From SVG 1.1 2nd Edition
+ // fill: 'shapes' and 'text content elements'
+ // stroke: 'shapes' and 'text content elements'
+ // -> altGlyph, circle, ellipse, line, path, polygon, polyline, rect, text, textPath, tref, tspan
+ struct FillStrokeData {
+ FillStrokeData()
+ : fill(0)
+ , stroke(0)
+ {
+ }
+
+ static PassOwnPtr<FillStrokeData> create()
+ {
+ return new FillStrokeData;
+ }
+
+ RenderSVGResourceContainer* fill;
+ RenderSVGResourceContainer* stroke;
+ };
+
+ OwnPtr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
+ OwnPtr<MarkerData> m_markerData;
+ OwnPtr<FillStrokeData> m_fillStrokeData;
};
}
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list