• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 namespace WebCore {
37 
SVGResources()38 SVGResources::SVGResources()
39     : m_clipperFilterMaskerData(0)
40     , m_markerData(0)
41     , m_fillStrokeData(0)
42     , m_linkedResource(0)
43 {
44 }
45 
clipperFilterMaskerTags()46 static HashSet<AtomicStringImpl*>& clipperFilterMaskerTags()
47 {
48     DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, 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().impl());
53         s_tagList.add(SVGNames::circleTag.localName().impl());
54         s_tagList.add(SVGNames::ellipseTag.localName().impl());
55         s_tagList.add(SVGNames::glyphTag.localName().impl());
56         s_tagList.add(SVGNames::gTag.localName().impl());
57         s_tagList.add(SVGNames::imageTag.localName().impl());
58         s_tagList.add(SVGNames::lineTag.localName().impl());
59         s_tagList.add(SVGNames::markerTag.localName().impl());
60         s_tagList.add(SVGNames::maskTag.localName().impl());
61         s_tagList.add(SVGNames::missing_glyphTag.localName().impl());
62         s_tagList.add(SVGNames::pathTag.localName().impl());
63         s_tagList.add(SVGNames::polygonTag.localName().impl());
64         s_tagList.add(SVGNames::polylineTag.localName().impl());
65         s_tagList.add(SVGNames::rectTag.localName().impl());
66         s_tagList.add(SVGNames::svgTag.localName().impl());
67         s_tagList.add(SVGNames::textTag.localName().impl());
68         s_tagList.add(SVGNames::useTag.localName().impl());
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().impl());
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().impl());
79         s_tagList.add(SVGNames::textPathTag.localName().impl());
80         s_tagList.add(SVGNames::trefTag.localName().impl());
81         s_tagList.add(SVGNames::tspanTag.localName().impl());
82 
83         // Elements that we ignore, as it doesn't make any sense.
84         // defs, pattern, switch (FIXME: Mail SVG WG about these)
85         // symbol (is converted to a svg element, when referenced by use, we can safely ignore it.)
86     }
87 
88     return s_tagList;
89 }
90 
markerTags()91 static HashSet<AtomicStringImpl*>& markerTags()
92 {
93     DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
94     if (s_tagList.isEmpty()) {
95         s_tagList.add(SVGNames::lineTag.localName().impl());
96         s_tagList.add(SVGNames::pathTag.localName().impl());
97         s_tagList.add(SVGNames::polygonTag.localName().impl());
98         s_tagList.add(SVGNames::polylineTag.localName().impl());
99     }
100 
101     return s_tagList;
102 }
103 
fillAndStrokeTags()104 static HashSet<AtomicStringImpl*>& fillAndStrokeTags()
105 {
106     DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
107     if (s_tagList.isEmpty()) {
108         s_tagList.add(SVGNames::altGlyphTag.localName().impl());
109         s_tagList.add(SVGNames::circleTag.localName().impl());
110         s_tagList.add(SVGNames::ellipseTag.localName().impl());
111         s_tagList.add(SVGNames::lineTag.localName().impl());
112         s_tagList.add(SVGNames::pathTag.localName().impl());
113         s_tagList.add(SVGNames::polygonTag.localName().impl());
114         s_tagList.add(SVGNames::polylineTag.localName().impl());
115         s_tagList.add(SVGNames::rectTag.localName().impl());
116         s_tagList.add(SVGNames::textTag.localName().impl());
117         s_tagList.add(SVGNames::textPathTag.localName().impl());
118         s_tagList.add(SVGNames::trefTag.localName().impl());
119         s_tagList.add(SVGNames::tspanTag.localName().impl());
120     }
121 
122     return s_tagList;
123 }
124 
chainableResourceTags()125 static HashSet<AtomicStringImpl*>& chainableResourceTags()
126 {
127     DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
128     if (s_tagList.isEmpty()) {
129         s_tagList.add(SVGNames::linearGradientTag.localName().impl());
130         s_tagList.add(SVGNames::filterTag.localName().impl());
131         s_tagList.add(SVGNames::patternTag.localName().impl());
132         s_tagList.add(SVGNames::radialGradientTag.localName().impl());
133     }
134 
135     return s_tagList;
136 }
137 
targetReferenceFromResource(SVGElement * element)138 static inline String targetReferenceFromResource(SVGElement* element)
139 {
140     String target;
141     if (element->hasTagName(SVGNames::patternTag))
142         target = static_cast<SVGPatternElement*>(element)->href();
143     else if (element->hasTagName(SVGNames::linearGradientTag) || element->hasTagName(SVGNames::radialGradientTag))
144         target = static_cast<SVGGradientElement*>(element)->href();
145 #if ENABLE(FILTERS)
146     else if (element->hasTagName(SVGNames::filterTag))
147         target = static_cast<SVGFilterElement*>(element)->href();
148 #endif
149     else
150         ASSERT_NOT_REACHED();
151 
152     return SVGURIReference::getTarget(target);
153 }
154 
paintingResourceFromSVGPaint(Document * document,SVGPaint * paint,AtomicString & id,bool & hasPendingResource)155 static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, SVGPaint* paint, AtomicString& id, bool& hasPendingResource)
156 {
157     ASSERT(paint);
158 
159     SVGPaint::SVGPaintType paintType = paint->paintType();
160     if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
161         return 0;
162 
163     id = SVGURIReference::getTarget(paint->uri());
164     RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id);
165     if (!container) {
166         hasPendingResource = true;
167         return 0;
168     }
169 
170     RenderSVGResourceType resourceType = container->resourceType();
171     if (resourceType != PatternResourceType && resourceType != LinearGradientResourceType && resourceType != RadialGradientResourceType)
172         return 0;
173 
174     return container;
175 }
176 
registerPendingResource(SVGDocumentExtensions * extensions,const AtomicString & id,SVGElement * element)177 static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, SVGElement* element)
178 {
179     ASSERT(element);
180     if (!element->isStyled())
181         return;
182 
183     extensions->addPendingResource(id, static_cast<SVGStyledElement*>(element));
184 }
185 
buildCachedResources(const RenderObject * object,const SVGRenderStyle * style)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->fillPaint(), 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->strokePaint(), 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 
removeClientFromCache(RenderObject * object,bool markForInvalidation) const289 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 
resourceDestroyed(RenderSVGResourceContainer * resource)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 
buildSetOfResources(HashSet<RenderSVGResourceContainer * > & set)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 
setClipper(RenderSVGResourceClipper * clipper)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 
resetClipper()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)
setFilter(RenderSVGResourceFilter * filter)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 
resetFilter()486 void SVGResources::resetFilter()
487 {
488     ASSERT(m_clipperFilterMaskerData);
489     ASSERT(m_clipperFilterMaskerData->filter);
490     m_clipperFilterMaskerData->filter = 0;
491 }
492 #endif
493 
setMarkerStart(RenderSVGResourceMarker * markerStart)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 
resetMarkerStart()508 void SVGResources::resetMarkerStart()
509 {
510     ASSERT(m_markerData);
511     ASSERT(m_markerData->markerStart);
512     m_markerData->markerStart = 0;
513 }
514 
setMarkerMid(RenderSVGResourceMarker * markerMid)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 
resetMarkerMid()529 void SVGResources::resetMarkerMid()
530 {
531     ASSERT(m_markerData);
532     ASSERT(m_markerData->markerMid);
533     m_markerData->markerMid = 0;
534 }
535 
setMarkerEnd(RenderSVGResourceMarker * markerEnd)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 
resetMarkerEnd()550 void SVGResources::resetMarkerEnd()
551 {
552     ASSERT(m_markerData);
553     ASSERT(m_markerData->markerEnd);
554     m_markerData->markerEnd = 0;
555 }
556 
setMasker(RenderSVGResourceMasker * masker)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 
resetMasker()571 void SVGResources::resetMasker()
572 {
573     ASSERT(m_clipperFilterMaskerData);
574     ASSERT(m_clipperFilterMaskerData->masker);
575     m_clipperFilterMaskerData->masker = 0;
576 }
577 
setFill(RenderSVGResourceContainer * fill)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 
resetFill()594 void SVGResources::resetFill()
595 {
596     ASSERT(m_fillStrokeData);
597     ASSERT(m_fillStrokeData->fill);
598     m_fillStrokeData->fill = 0;
599 }
600 
setStroke(RenderSVGResourceContainer * stroke)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 
resetStroke()617 void SVGResources::resetStroke()
618 {
619     ASSERT(m_fillStrokeData);
620     ASSERT(m_fillStrokeData->stroke);
621     m_fillStrokeData->stroke = 0;
622 }
623 
setLinkedResource(RenderSVGResourceContainer * linkedResource)624 bool SVGResources::setLinkedResource(RenderSVGResourceContainer* linkedResource)
625 {
626     if (!linkedResource)
627         return false;
628 
629     m_linkedResource = linkedResource;
630     return true;
631 }
632 
resetLinkedResource()633 void SVGResources::resetLinkedResource()
634 {
635     ASSERT(m_linkedResource);
636     m_linkedResource = 0;
637 }
638 
639 #ifndef NDEBUG
dump(const RenderObject * object)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
685