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