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