Home | History | Annotate | Download | only in svg
      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 
     38 SVGResources::SVGResources()
     39     : m_clipperFilterMaskerData(0)
     40     , m_markerData(0)
     41     , m_fillStrokeData(0)
     42     , m_linkedResource(0)
     43 {
     44 }
     45 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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
    685