Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / svg / SVGResources.cpp
1 /*
2  * Copyright (C) Research In Motion Limited 2010. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include "config.h"
21 #include "core/rendering/svg/SVGResources.h"
22
23 #include "core/SVGNames.h"
24 #include "core/rendering/style/SVGRenderStyle.h"
25 #include "core/rendering/svg/RenderSVGResourceClipper.h"
26 #include "core/rendering/svg/RenderSVGResourceFilter.h"
27 #include "core/rendering/svg/RenderSVGResourceMarker.h"
28 #include "core/rendering/svg/RenderSVGResourceMasker.h"
29 #include "core/rendering/svg/RenderSVGResourcePaintServer.h"
30 #include "core/svg/SVGFilterElement.h"
31 #include "core/svg/SVGGradientElement.h"
32 #include "core/svg/SVGPatternElement.h"
33 #include "core/svg/SVGURIReference.h"
34
35 #ifndef NDEBUG
36 #include <stdio.h>
37 #endif
38
39 namespace blink {
40
41 using namespace SVGNames;
42
43 SVGResources::SVGResources()
44     : m_linkedResource(0)
45 {
46 }
47
48 static HashSet<AtomicString>& clipperFilterMaskerTags()
49 {
50     DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
51     if (s_tagList.isEmpty()) {
52         // "container elements": http://www.w3.org/TR/SVG11/intro.html#TermContainerElement
53         // "graphics elements" : http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement
54         s_tagList.add(aTag.localName());
55         s_tagList.add(circleTag.localName());
56         s_tagList.add(ellipseTag.localName());
57         s_tagList.add(gTag.localName());
58         s_tagList.add(imageTag.localName());
59         s_tagList.add(lineTag.localName());
60         s_tagList.add(markerTag.localName());
61         s_tagList.add(maskTag.localName());
62         s_tagList.add(pathTag.localName());
63         s_tagList.add(polygonTag.localName());
64         s_tagList.add(polylineTag.localName());
65         s_tagList.add(rectTag.localName());
66         s_tagList.add(svgTag.localName());
67         s_tagList.add(textTag.localName());
68         s_tagList.add(useTag.localName());
69
70         // Not listed in the definitions is the clipPath element, the SVG spec says though:
71         // The "clipPath" element or any of its children can specify property "clip-path".
72         // So we have to add clipPathTag here, otherwhise clip-path on clipPath will fail.
73         // (Already mailed SVG WG, waiting for a solution)
74         s_tagList.add(clipPathTag.localName());
75
76         // Not listed in the definitions are the text content elements, though filter/clipper/masker on tspan/text/.. is allowed.
77         // (Already mailed SVG WG, waiting for a solution)
78         s_tagList.add(textPathTag.localName());
79         s_tagList.add(tspanTag.localName());
80
81         // Not listed in the definitions is the foreignObject element, but clip-path
82         // is a supported attribute.
83         s_tagList.add(foreignObjectTag.localName());
84
85         // Elements that we ignore, as it doesn't make any sense.
86         // defs, pattern, switch (FIXME: Mail SVG WG about these)
87         // symbol (is converted to a svg element, when referenced by use, we can safely ignore it.)
88     }
89
90     return s_tagList;
91 }
92
93 bool SVGResources::supportsMarkers(const SVGElement& element)
94 {
95     DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
96     if (s_tagList.isEmpty()) {
97         s_tagList.add(lineTag.localName());
98         s_tagList.add(pathTag.localName());
99         s_tagList.add(polygonTag.localName());
100         s_tagList.add(polylineTag.localName());
101     }
102
103     return s_tagList.contains(element.localName());
104 }
105
106 static HashSet<AtomicString>& fillAndStrokeTags()
107 {
108     DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
109     if (s_tagList.isEmpty()) {
110         s_tagList.add(circleTag.localName());
111         s_tagList.add(ellipseTag.localName());
112         s_tagList.add(lineTag.localName());
113         s_tagList.add(pathTag.localName());
114         s_tagList.add(polygonTag.localName());
115         s_tagList.add(polylineTag.localName());
116         s_tagList.add(rectTag.localName());
117         s_tagList.add(textTag.localName());
118         s_tagList.add(textPathTag.localName());
119         s_tagList.add(tspanTag.localName());
120     }
121
122     return s_tagList;
123 }
124
125 static HashSet<AtomicString>& chainableResourceTags()
126 {
127     DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
128     if (s_tagList.isEmpty()) {
129         s_tagList.add(linearGradientTag.localName());
130         s_tagList.add(filterTag.localName());
131         s_tagList.add(patternTag.localName());
132         s_tagList.add(radialGradientTag.localName());
133     }
134
135     return s_tagList;
136 }
137
138 static inline AtomicString targetReferenceFromResource(SVGElement& element)
139 {
140     String target;
141     if (isSVGPatternElement(element))
142         target = toSVGPatternElement(element).href()->currentValue()->value();
143     else if (isSVGGradientElement(element))
144         target = toSVGGradientElement(element).href()->currentValue()->value();
145     else if (isSVGFilterElement(element))
146         target = toSVGFilterElement(element).href()->currentValue()->value();
147     else
148         ASSERT_NOT_REACHED();
149
150     return SVGURIReference::fragmentIdentifierFromIRIString(target, element.treeScope());
151 }
152
153 static inline bool svgPaintTypeHasURL(SVGPaintType paintType)
154 {
155     switch (paintType) {
156     case SVG_PAINTTYPE_URI_NONE:
157     case SVG_PAINTTYPE_URI_CURRENTCOLOR:
158     case SVG_PAINTTYPE_URI_RGBCOLOR:
159     case SVG_PAINTTYPE_URI:
160         return true;
161     default:
162         break;
163     }
164     return false;
165 }
166
167 static inline RenderSVGResourcePaintServer* paintingResourceFromSVGPaint(TreeScope& treeScope, const SVGPaintType& paintType, const String& paintUri, AtomicString& id, bool& hasPendingResource)
168 {
169     if (!svgPaintTypeHasURL(paintType))
170         return 0;
171
172     id = SVGURIReference::fragmentIdentifierFromIRIString(paintUri, treeScope);
173     RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(treeScope, id);
174     if (!container) {
175         hasPendingResource = true;
176         return 0;
177     }
178
179     if (!container->isSVGPaintServer())
180         return 0;
181
182     return toRenderSVGResourcePaintServer(container);
183 }
184
185 static inline void registerPendingResource(SVGDocumentExtensions& extensions, const AtomicString& id, SVGElement* element)
186 {
187     ASSERT(element);
188     extensions.addPendingResource(id, element);
189 }
190
191 bool SVGResources::hasResourceData() const
192 {
193     return m_clipperFilterMaskerData
194         || m_markerData
195         || m_fillStrokeData
196         || m_linkedResource;
197 }
198
199 static inline SVGResources* ensureResources(OwnPtr<SVGResources>& resources)
200 {
201     if (!resources)
202         resources = adoptPtr(new SVGResources);
203
204     return resources.get();
205 }
206
207 PassOwnPtr<SVGResources> SVGResources::buildResources(const RenderObject* object, const SVGRenderStyle& style)
208 {
209     ASSERT(object);
210
211     Node* node = object->node();
212     ASSERT(node);
213     ASSERT_WITH_SECURITY_IMPLICATION(node->isSVGElement());
214
215     SVGElement* element = toSVGElement(node);
216     if (!element)
217         return nullptr;
218
219     TreeScope& treeScope = element->treeScope();
220
221     SVGDocumentExtensions& extensions = object->document().accessSVGExtensions();
222
223     const AtomicString& tagName = element->localName();
224     if (tagName.isNull())
225         return nullptr;
226
227     OwnPtr<SVGResources> resources;
228     if (clipperFilterMaskerTags().contains(tagName)) {
229         if (style.hasClipper()) {
230             AtomicString id = style.clipperResource();
231             if (!ensureResources(resources)->setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(treeScope, id)))
232                 registerPendingResource(extensions, id, element);
233         }
234
235         if (style.hasFilter()) {
236             AtomicString id = style.filterResource();
237             if (!ensureResources(resources)->setFilter(getRenderSVGResourceById<RenderSVGResourceFilter>(treeScope, id)))
238                 registerPendingResource(extensions, id, element);
239         }
240
241         if (style.hasMasker()) {
242             AtomicString id = style.maskerResource();
243             if (!ensureResources(resources)->setMasker(getRenderSVGResourceById<RenderSVGResourceMasker>(treeScope, id)))
244                 registerPendingResource(extensions, id, element);
245         }
246     }
247
248     if (style.hasMarkers() && supportsMarkers(*element)) {
249         const AtomicString& markerStartId = style.markerStartResource();
250         if (!ensureResources(resources)->setMarkerStart(getRenderSVGResourceById<RenderSVGResourceMarker>(treeScope, markerStartId)))
251             registerPendingResource(extensions, markerStartId, element);
252
253         const AtomicString& markerMidId = style.markerMidResource();
254         if (!ensureResources(resources)->setMarkerMid(getRenderSVGResourceById<RenderSVGResourceMarker>(treeScope, markerMidId)))
255             registerPendingResource(extensions, markerMidId, element);
256
257         const AtomicString& markerEndId = style.markerEndResource();
258         if (!ensureResources(resources)->setMarkerEnd(getRenderSVGResourceById<RenderSVGResourceMarker>(treeScope, style.markerEndResource())))
259             registerPendingResource(extensions, markerEndId, element);
260     }
261
262     if (fillAndStrokeTags().contains(tagName)) {
263         if (style.hasFill()) {
264             bool hasPendingResource = false;
265             AtomicString id;
266             RenderSVGResourcePaintServer* resource = paintingResourceFromSVGPaint(treeScope, style.fillPaintType(), style.fillPaintUri(), id, hasPendingResource);
267             if (!ensureResources(resources)->setFill(resource) && hasPendingResource) {
268                 registerPendingResource(extensions, id, element);
269             }
270         }
271
272         if (style.hasStroke()) {
273             bool hasPendingResource = false;
274             AtomicString id;
275             RenderSVGResourcePaintServer* resource = paintingResourceFromSVGPaint(treeScope, style.strokePaintType(), style.strokePaintUri(), id, hasPendingResource);
276             if (!ensureResources(resources)->setStroke(resource) && hasPendingResource) {
277                 registerPendingResource(extensions, id, element);
278             }
279         }
280     }
281
282     if (chainableResourceTags().contains(tagName)) {
283         AtomicString id = targetReferenceFromResource(*element);
284         if (!ensureResources(resources)->setLinkedResource(getRenderSVGResourceContainerById(treeScope, id)))
285             registerPendingResource(extensions, id, element);
286     }
287
288     return (!resources || !resources->hasResourceData()) ? nullptr : resources.release();
289 }
290
291 void SVGResources::layoutIfNeeded()
292 {
293     if (m_clipperFilterMaskerData) {
294         if (RenderSVGResourceClipper* clipper = m_clipperFilterMaskerData->clipper)
295             clipper->layoutIfNeeded();
296         if (RenderSVGResourceMasker* masker = m_clipperFilterMaskerData->masker)
297             masker->layoutIfNeeded();
298         if (RenderSVGResourceFilter* filter = m_clipperFilterMaskerData->filter)
299             filter->layoutIfNeeded();
300     }
301
302     if (m_markerData) {
303         if (RenderSVGResourceMarker* marker = m_markerData->markerStart)
304             marker->layoutIfNeeded();
305         if (RenderSVGResourceMarker* marker = m_markerData->markerMid)
306             marker->layoutIfNeeded();
307         if (RenderSVGResourceMarker* marker = m_markerData->markerEnd)
308             marker->layoutIfNeeded();
309     }
310
311     if (m_fillStrokeData) {
312         if (RenderSVGResourcePaintServer* fill = m_fillStrokeData->fill)
313             fill->layoutIfNeeded();
314         if (RenderSVGResourcePaintServer* stroke = m_fillStrokeData->stroke)
315             stroke->layoutIfNeeded();
316     }
317
318     if (m_linkedResource)
319         m_linkedResource->layoutIfNeeded();
320 }
321
322 void SVGResources::removeClientFromCache(RenderObject* object, bool markForInvalidation) const
323 {
324     if (!hasResourceData())
325         return;
326
327     if (m_linkedResource) {
328         ASSERT(!m_clipperFilterMaskerData);
329         ASSERT(!m_markerData);
330         ASSERT(!m_fillStrokeData);
331         m_linkedResource->removeClientFromCache(object, markForInvalidation);
332         return;
333     }
334
335     if (m_clipperFilterMaskerData) {
336         if (m_clipperFilterMaskerData->clipper)
337             m_clipperFilterMaskerData->clipper->removeClientFromCache(object, markForInvalidation);
338         if (m_clipperFilterMaskerData->filter)
339             m_clipperFilterMaskerData->filter->removeClientFromCache(object, markForInvalidation);
340         if (m_clipperFilterMaskerData->masker)
341             m_clipperFilterMaskerData->masker->removeClientFromCache(object, markForInvalidation);
342     }
343
344     if (m_markerData) {
345         if (m_markerData->markerStart)
346             m_markerData->markerStart->removeClientFromCache(object, markForInvalidation);
347         if (m_markerData->markerMid)
348             m_markerData->markerMid->removeClientFromCache(object, markForInvalidation);
349         if (m_markerData->markerEnd)
350             m_markerData->markerEnd->removeClientFromCache(object, markForInvalidation);
351     }
352
353     if (m_fillStrokeData) {
354         if (m_fillStrokeData->fill)
355             m_fillStrokeData->fill->removeClientFromCache(object, markForInvalidation);
356         if (m_fillStrokeData->stroke)
357             m_fillStrokeData->stroke->removeClientFromCache(object, markForInvalidation);
358     }
359 }
360
361 void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
362 {
363     ASSERT(resource);
364     if (!hasResourceData())
365         return;
366
367     if (m_linkedResource == resource) {
368         ASSERT(!m_clipperFilterMaskerData);
369         ASSERT(!m_markerData);
370         ASSERT(!m_fillStrokeData);
371         m_linkedResource->removeAllClientsFromCache();
372         m_linkedResource = 0;
373         return;
374     }
375
376     switch (resource->resourceType()) {
377     case MaskerResourceType:
378         if (!m_clipperFilterMaskerData)
379             break;
380         if (m_clipperFilterMaskerData->masker == resource) {
381             m_clipperFilterMaskerData->masker->removeAllClientsFromCache();
382             m_clipperFilterMaskerData->masker = 0;
383         }
384         break;
385     case MarkerResourceType:
386         if (!m_markerData)
387             break;
388         if (m_markerData->markerStart == resource) {
389             m_markerData->markerStart->removeAllClientsFromCache();
390             m_markerData->markerStart = 0;
391         }
392         if (m_markerData->markerMid == resource) {
393             m_markerData->markerMid->removeAllClientsFromCache();
394             m_markerData->markerMid = 0;
395         }
396         if (m_markerData->markerEnd == resource) {
397             m_markerData->markerEnd->removeAllClientsFromCache();
398             m_markerData->markerEnd = 0;
399         }
400         break;
401     case PatternResourceType:
402     case LinearGradientResourceType:
403     case RadialGradientResourceType:
404         if (!m_fillStrokeData)
405             break;
406         if (m_fillStrokeData->fill == resource) {
407             m_fillStrokeData->fill->removeAllClientsFromCache();
408             m_fillStrokeData->fill = 0;
409         }
410         if (m_fillStrokeData->stroke == resource) {
411             m_fillStrokeData->stroke->removeAllClientsFromCache();
412             m_fillStrokeData->stroke = 0;
413         }
414         break;
415     case FilterResourceType:
416         if (!m_clipperFilterMaskerData)
417             break;
418         if (m_clipperFilterMaskerData->filter == resource) {
419             m_clipperFilterMaskerData->filter->removeAllClientsFromCache();
420             m_clipperFilterMaskerData->filter = 0;
421         }
422         break;
423     case ClipperResourceType:
424         if (!m_clipperFilterMaskerData)
425             break;
426         if (m_clipperFilterMaskerData->clipper == resource) {
427             m_clipperFilterMaskerData->clipper->removeAllClientsFromCache();
428             m_clipperFilterMaskerData->clipper = 0;
429         }
430         break;
431     default:
432         ASSERT_NOT_REACHED();
433     }
434 }
435
436 void SVGResources::buildSetOfResources(HashSet<RenderSVGResourceContainer*>& set)
437 {
438     if (!hasResourceData())
439         return;
440
441     if (m_linkedResource) {
442         ASSERT(!m_clipperFilterMaskerData);
443         ASSERT(!m_markerData);
444         ASSERT(!m_fillStrokeData);
445         set.add(m_linkedResource);
446         return;
447     }
448
449     if (m_clipperFilterMaskerData) {
450         if (m_clipperFilterMaskerData->clipper)
451             set.add(m_clipperFilterMaskerData->clipper);
452         if (m_clipperFilterMaskerData->filter)
453             set.add(m_clipperFilterMaskerData->filter);
454         if (m_clipperFilterMaskerData->masker)
455             set.add(m_clipperFilterMaskerData->masker);
456     }
457
458     if (m_markerData) {
459         if (m_markerData->markerStart)
460             set.add(m_markerData->markerStart);
461         if (m_markerData->markerMid)
462             set.add(m_markerData->markerMid);
463         if (m_markerData->markerEnd)
464             set.add(m_markerData->markerEnd);
465     }
466
467     if (m_fillStrokeData) {
468         if (m_fillStrokeData->fill)
469             set.add(m_fillStrokeData->fill);
470         if (m_fillStrokeData->stroke)
471             set.add(m_fillStrokeData->stroke);
472     }
473 }
474
475 bool SVGResources::setClipper(RenderSVGResourceClipper* clipper)
476 {
477     if (!clipper)
478         return false;
479
480     ASSERT(clipper->resourceType() == ClipperResourceType);
481
482     if (!m_clipperFilterMaskerData)
483         m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
484
485     m_clipperFilterMaskerData->clipper = clipper;
486     return true;
487 }
488
489 void SVGResources::resetClipper()
490 {
491     ASSERT(m_clipperFilterMaskerData);
492     ASSERT(m_clipperFilterMaskerData->clipper);
493     m_clipperFilterMaskerData->clipper = 0;
494 }
495
496 bool SVGResources::setFilter(RenderSVGResourceFilter* filter)
497 {
498     if (!filter)
499         return false;
500
501     ASSERT(filter->resourceType() == FilterResourceType);
502
503     if (!m_clipperFilterMaskerData)
504         m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
505
506     m_clipperFilterMaskerData->filter = filter;
507     return true;
508 }
509
510 void SVGResources::resetFilter()
511 {
512     ASSERT(m_clipperFilterMaskerData);
513     ASSERT(m_clipperFilterMaskerData->filter);
514     m_clipperFilterMaskerData->filter = 0;
515 }
516
517 bool SVGResources::setMarkerStart(RenderSVGResourceMarker* markerStart)
518 {
519     if (!markerStart)
520         return false;
521
522     ASSERT(markerStart->resourceType() == MarkerResourceType);
523
524     if (!m_markerData)
525         m_markerData = MarkerData::create();
526
527     m_markerData->markerStart = markerStart;
528     return true;
529 }
530
531 void SVGResources::resetMarkerStart()
532 {
533     ASSERT(m_markerData);
534     ASSERT(m_markerData->markerStart);
535     m_markerData->markerStart = 0;
536 }
537
538 bool SVGResources::setMarkerMid(RenderSVGResourceMarker* markerMid)
539 {
540     if (!markerMid)
541         return false;
542
543     ASSERT(markerMid->resourceType() == MarkerResourceType);
544
545     if (!m_markerData)
546         m_markerData = MarkerData::create();
547
548     m_markerData->markerMid = markerMid;
549     return true;
550 }
551
552 void SVGResources::resetMarkerMid()
553 {
554     ASSERT(m_markerData);
555     ASSERT(m_markerData->markerMid);
556     m_markerData->markerMid = 0;
557 }
558
559 bool SVGResources::setMarkerEnd(RenderSVGResourceMarker* markerEnd)
560 {
561     if (!markerEnd)
562         return false;
563
564     ASSERT(markerEnd->resourceType() == MarkerResourceType);
565
566     if (!m_markerData)
567         m_markerData = MarkerData::create();
568
569     m_markerData->markerEnd = markerEnd;
570     return true;
571 }
572
573 void SVGResources::resetMarkerEnd()
574 {
575     ASSERT(m_markerData);
576     ASSERT(m_markerData->markerEnd);
577     m_markerData->markerEnd = 0;
578 }
579
580 bool SVGResources::setMasker(RenderSVGResourceMasker* masker)
581 {
582     if (!masker)
583         return false;
584
585     ASSERT(masker->resourceType() == MaskerResourceType);
586
587     if (!m_clipperFilterMaskerData)
588         m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
589
590     m_clipperFilterMaskerData->masker = masker;
591     return true;
592 }
593
594 void SVGResources::resetMasker()
595 {
596     ASSERT(m_clipperFilterMaskerData);
597     ASSERT(m_clipperFilterMaskerData->masker);
598     m_clipperFilterMaskerData->masker = 0;
599 }
600
601 bool SVGResources::setFill(RenderSVGResourcePaintServer* fill)
602 {
603     if (!fill)
604         return false;
605
606     if (!m_fillStrokeData)
607         m_fillStrokeData = FillStrokeData::create();
608
609     m_fillStrokeData->fill = fill;
610     return true;
611 }
612
613 void SVGResources::resetFill()
614 {
615     ASSERT(m_fillStrokeData);
616     ASSERT(m_fillStrokeData->fill);
617     m_fillStrokeData->fill = 0;
618 }
619
620 bool SVGResources::setStroke(RenderSVGResourcePaintServer* stroke)
621 {
622     if (!stroke)
623         return false;
624
625     if (!m_fillStrokeData)
626         m_fillStrokeData = FillStrokeData::create();
627
628     m_fillStrokeData->stroke = stroke;
629     return true;
630 }
631
632 void SVGResources::resetStroke()
633 {
634     ASSERT(m_fillStrokeData);
635     ASSERT(m_fillStrokeData->stroke);
636     m_fillStrokeData->stroke = 0;
637 }
638
639 bool SVGResources::setLinkedResource(RenderSVGResourceContainer* linkedResource)
640 {
641     if (!linkedResource)
642         return false;
643
644     m_linkedResource = linkedResource;
645     return true;
646 }
647
648 void SVGResources::resetLinkedResource()
649 {
650     ASSERT(m_linkedResource);
651     m_linkedResource = 0;
652 }
653
654 #ifndef NDEBUG
655 void SVGResources::dump(const RenderObject* object)
656 {
657     ASSERT(object);
658     ASSERT(object->node());
659
660     fprintf(stderr, "-> this=%p, SVGResources(renderer=%p, node=%p)\n", this, object, object->node());
661     fprintf(stderr, " | DOM Tree:\n");
662     object->node()->showTreeForThis();
663
664     fprintf(stderr, "\n | List of resources:\n");
665     if (m_clipperFilterMaskerData) {
666         if (RenderSVGResourceClipper* clipper = m_clipperFilterMaskerData->clipper)
667             fprintf(stderr, " |-> Clipper    : %p (node=%p)\n", clipper, clipper->element());
668         if (RenderSVGResourceFilter* filter = m_clipperFilterMaskerData->filter)
669             fprintf(stderr, " |-> Filter     : %p (node=%p)\n", filter, filter->element());
670         if (RenderSVGResourceMasker* masker = m_clipperFilterMaskerData->masker)
671             fprintf(stderr, " |-> Masker     : %p (node=%p)\n", masker, masker->element());
672     }
673
674     if (m_markerData) {
675         if (RenderSVGResourceMarker* markerStart = m_markerData->markerStart)
676             fprintf(stderr, " |-> MarkerStart: %p (node=%p)\n", markerStart, markerStart->element());
677         if (RenderSVGResourceMarker* markerMid = m_markerData->markerMid)
678             fprintf(stderr, " |-> MarkerMid  : %p (node=%p)\n", markerMid, markerMid->element());
679         if (RenderSVGResourceMarker* markerEnd = m_markerData->markerEnd)
680             fprintf(stderr, " |-> MarkerEnd  : %p (node=%p)\n", markerEnd, markerEnd->element());
681     }
682
683     if (m_fillStrokeData) {
684         if (RenderSVGResourcePaintServer* fill = m_fillStrokeData->fill)
685             fprintf(stderr, " |-> Fill       : %p (node=%p)\n", fill, fill->element());
686         if (RenderSVGResourcePaintServer* stroke = m_fillStrokeData->stroke)
687             fprintf(stderr, " |-> Stroke     : %p (node=%p)\n", stroke, stroke->element());
688     }
689
690     if (m_linkedResource)
691         fprintf(stderr, " |-> xlink:href : %p (node=%p)\n", m_linkedResource, m_linkedResource->element());
692 }
693 #endif
694
695 }