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#pragma once
21
22#include "RenderSVGHiddenContainer.h"
23#include "RenderSVGResource.h"
24#include "SVGDocumentExtensions.h"
25
26namespace WebCore {
27
28class RenderLayer;
29
30class RenderSVGResourceContainer : public RenderSVGHiddenContainer,
31 public RenderSVGResource {
32 WTF_MAKE_ISO_ALLOCATED(RenderSVGResourceContainer);
33public:
34 virtual ~RenderSVGResourceContainer();
35
36 void layout() override;
37 void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
38
39 bool isSVGResourceContainer() const final { return true; }
40
41 static bool shouldTransformOnTextPainting(const RenderElement&, AffineTransform&);
42 static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
43
44 void idChanged();
45 void addClientRenderLayer(RenderLayer*);
46 void removeClientRenderLayer(RenderLayer*);
47
48protected:
49 RenderSVGResourceContainer(SVGElement&, RenderStyle&&);
50
51 enum InvalidationMode {
52 LayoutAndBoundariesInvalidation,
53 BoundariesInvalidation,
54 RepaintInvalidation,
55 ParentOnlyInvalidation
56 };
57
58 // Used from the invalidateClient/invalidateClients methods from classes, inheriting from us.
59 virtual bool selfNeedsClientInvalidation() const { return everHadLayout() && selfNeedsLayout(); }
60
61 void markAllClientsForInvalidation(InvalidationMode);
62 void markAllClientLayersForInvalidation();
63 void markClientForInvalidation(RenderObject&, InvalidationMode);
64
65private:
66 friend class SVGResourcesCache;
67 void addClient(RenderElement&);
68 void removeClient(RenderElement&);
69
70 void willBeDestroyed() final;
71 void registerResource();
72
73 AtomicString m_id;
74 HashSet<RenderElement*> m_clients;
75 HashSet<RenderLayer*> m_clientLayers;
76 bool m_registered { false };
77 bool m_isInvalidating { false };
78};
79
80inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(Document& document, const AtomicString& id)
81{
82 if (id.isEmpty())
83 return nullptr;
84
85 if (RenderSVGResourceContainer* renderResource = document.accessSVGExtensions().resourceById(id))
86 return renderResource;
87
88 return nullptr;
89}
90
91template<typename Renderer>
92Renderer* getRenderSVGResourceById(Document& document, const AtomicString& id)
93{
94 // Using the RenderSVGResource type here avoids ambiguous casts for types that
95 // descend from both RenderObject and RenderSVGResourceContainer.
96 RenderSVGResource* container = getRenderSVGResourceContainerById(document, id);
97 if (is<Renderer>(container))
98 return downcast<Renderer>(container);
99
100 return nullptr;
101}
102
103} // namespace WebCore
104
105SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGResourceContainer, isSVGResourceContainer())
106