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#ifndef RenderSVGResourceContainer_h
21#define RenderSVGResourceContainer_h
22
23#include "core/rendering/svg/RenderSVGHiddenContainer.h"
24#include "core/rendering/svg/RenderSVGResource.h"
25#include "core/svg/SVGDocumentExtensions.h"
26
27namespace blink {
28
29class RenderLayer;
30
31class RenderSVGResourceContainer : public RenderSVGHiddenContainer,
32                                   public RenderSVGResource {
33public:
34    explicit RenderSVGResourceContainer(SVGElement*);
35    virtual ~RenderSVGResourceContainer();
36
37    virtual void layout() OVERRIDE;
38    virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
39
40    virtual bool isSVGResourceContainer() const OVERRIDE FINAL { return true; }
41
42    static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
43
44    void idChanged();
45    void addClientRenderLayer(Node*);
46    void addClientRenderLayer(RenderLayer*);
47    void removeClientRenderLayer(RenderLayer*);
48
49    void invalidateCacheAndMarkForLayout(SubtreeLayoutScope* = 0);
50
51protected:
52    // When adding modes, make sure we don't overflow m_invalidationMask below.
53    enum InvalidationMode {
54        LayoutAndBoundariesInvalidation = 1 << 0,
55        BoundariesInvalidation = 1 << 1,
56        PaintInvalidation = 1 << 2,
57        ParentOnlyInvalidation = 1 << 3
58    };
59
60    // Used from the invalidateClient/invalidateClients methods from classes, inheriting from us.
61    void markAllClientsForInvalidation(InvalidationMode);
62    void markAllClientLayersForInvalidation();
63    void markClientForInvalidation(RenderObject*, InvalidationMode);
64
65    void clearInvalidationMask() { m_invalidationMask = 0; }
66
67    static AffineTransform computeResourceSpaceTransform(RenderObject*, const AffineTransform& baseTransform, const SVGRenderStyle&, unsigned short resourceMode);
68
69    bool m_isInLayout;
70
71private:
72    friend class SVGResourcesCache;
73    void addClient(RenderObject*);
74    void removeClient(RenderObject*);
75
76    virtual void willBeDestroyed() OVERRIDE FINAL;
77    void registerResource();
78
79    AtomicString m_id;
80    // Track global (markAllClientsForInvalidation) invals to avoid redundant crawls.
81    unsigned m_invalidationMask : 8;
82
83    bool m_registered : 1;
84    bool m_isInvalidating : 1;
85    // 22 padding bits available
86
87    HashSet<RenderObject*> m_clients;
88    HashSet<RenderLayer*> m_clientLayers;
89};
90
91inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(TreeScope& treeScope, const AtomicString& id)
92{
93    if (id.isEmpty())
94        return 0;
95
96    if (RenderSVGResourceContainer* renderResource = treeScope.document().accessSVGExtensions().resourceById(id))
97        return renderResource;
98
99    return 0;
100}
101
102template<typename Renderer>
103Renderer* getRenderSVGResourceById(TreeScope& treeScope, const AtomicString& id)
104{
105    if (RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(treeScope, id))
106        return container->cast<Renderer>();
107
108    return 0;
109}
110
111DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderSVGResourceContainer, isSVGResourceContainer());
112
113}
114
115#endif
116