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