text: /*
   * Copyright (C) Research In Motion Limited 2010. All rights reserved.
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Library General Public
   * License as published by the Free Software Foundation; either
   * version 2 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Library General Public License for more details.
   *
   * You should have received a copy of the GNU Library General Public License
   * along with this library; see the file COPYING.LIB.  If not, write to
   * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   * Boston, MA 02110-1301, USA.
   */
  
  #ifndef SVGResources_h
  #define SVGResources_h
  
  #include "wtf/FastAllocBase.h"
  #include "wtf/HashSet.h"
  #include "wtf/Noncopyable.h"
  #include "wtf/OwnPtr.h"
  #include "wtf/PassOwnPtr.h"
  
  namespace blink {
  
  class RenderObject;
  class RenderSVGResourceClipper;
  class RenderSVGResourceContainer;
  class RenderSVGResourceFilter;
  class RenderSVGResourceMarker;
  class RenderSVGResourceMasker;
  class RenderSVGResourcePaintServer;
  class SVGElement;
  class SVGRenderStyle;
  
  // Holds a set of resources associated with a RenderObject
  class SVGResources {
      WTF_MAKE_NONCOPYABLE(SVGResources); WTF_MAKE_FAST_ALLOCATED;
  public:
      SVGResources();
  
      static PassOwnPtr<SVGResources> buildResources(const RenderObject*, const SVGRenderStyle&);
      void layoutIfNeeded();
  
      static bool supportsMarkers(const SVGElement&);
  
      // Ordinary resources
      RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
      RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
      RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
      RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
      RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
  
      RenderSVGResourceFilter* filter() const
      {
          if (m_clipperFilterMaskerData)
              return m_clipperFilterMaskerData->filter;
          return 0;
      }
  
      // Paint servers
      RenderSVGResourcePaintServer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
      RenderSVGResourcePaintServer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
  
      // Chainable resources - linked through xlink:href
      RenderSVGResourceContainer* linkedResource() const { return m_linkedResource; }
  
      void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
  
      // Methods operating on all cached resources
      void removeClientFromCache(RenderObject*, bool markForInvalidation = true) const;
      void resourceDestroyed(RenderSVGResourceContainer*);
  
  #ifndef NDEBUG
      void dump(const RenderObject*);
  #endif
  
  private:
      friend class SVGResourcesCycleSolver;
  
      bool hasResourceData() const;
  
      // Only used by SVGResourcesCache cycle detection logic
      void resetClipper();
      void resetFilter();
      void resetMarkerStart();
      void resetMarkerMid();
      void resetMarkerEnd();
      void resetMasker();
      void resetFill();
      void resetStroke();
      void resetLinkedResource();
  
      bool setClipper(RenderSVGResourceClipper*);
      bool setFilter(RenderSVGResourceFilter*);
      bool setMarkerStart(RenderSVGResourceMarker*);
      bool setMarkerMid(RenderSVGResourceMarker*);
      bool setMarkerEnd(RenderSVGResourceMarker*);
      bool setMasker(RenderSVGResourceMasker*);
      bool setFill(RenderSVGResourcePaintServer*);
      bool setStroke(RenderSVGResourcePaintServer*);
      bool setLinkedResource(RenderSVGResourceContainer*);
  
      // From SVG 1.1 2nd Edition
      // clipper: 'container elements' and 'graphics elements'
      // filter:  'container elements' and 'graphics elements'
      // masker:  'container elements' and 'graphics elements'
      // -> a, circle, defs, ellipse, glyph, g, image, line, marker, mask, missing-glyph, path, pattern, polygon, polyline, rect, svg, switch, symbol, text, use
      struct ClipperFilterMaskerData {
          WTF_MAKE_FAST_ALLOCATED;
      public:
          ClipperFilterMaskerData()
              : clipper(0)
              , filter(0)
              , masker(0)
          {
          }
  
          static PassOwnPtr<ClipperFilterMaskerData> create()
          {
              return adoptPtr(new ClipperFilterMaskerData);
          }
  
          RenderSVGResourceClipper* clipper;
          RenderSVGResourceFilter* filter;
          RenderSVGResourceMasker* masker;
      };
  
      // From SVG 1.1 2nd Edition
      // marker: line, path, polygon, polyline
      struct MarkerData {
          WTF_MAKE_FAST_ALLOCATED;
      public:
          MarkerData()
              : markerStart(0)
              , markerMid(0)
              , markerEnd(0)
          {
          }
  
          static PassOwnPtr<MarkerData> create()
          {
              return adoptPtr(new MarkerData);
          }
  
          RenderSVGResourceMarker* markerStart;
          RenderSVGResourceMarker* markerMid;
          RenderSVGResourceMarker* markerEnd;
      };
  
      // From SVG 1.1 2nd Edition
      // fill:       'shapes' and 'text content elements'
      // stroke:     'shapes' and 'text content elements'
      // -> circle, ellipse, line, path, polygon, polyline, rect, text, textPath, tspan
      struct FillStrokeData {
          WTF_MAKE_FAST_ALLOCATED;
      public:
          FillStrokeData()
              : fill(0)
              , stroke(0)
          {
          }
  
          static PassOwnPtr<FillStrokeData> create()
          {
              return adoptPtr(new FillStrokeData);
          }
  
          RenderSVGResourcePaintServer* fill;
          RenderSVGResourcePaintServer* stroke;
      };
  
      OwnPtr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
      OwnPtr<MarkerData> m_markerData;
      OwnPtr<FillStrokeData> m_fillStrokeData;
      RenderSVGResourceContainer* m_linkedResource;
  };
  
  }
  
  #endif
  