layout/svg/nsSVGGradientFrame.h

branch
TOR_BUG_9701
changeset 8
97036ab72558
equal deleted inserted replaced
-1:000000000000 0:edc61a47faa1
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 #ifndef __NS_SVGGRADIENTFRAME_H__
7 #define __NS_SVGGRADIENTFRAME_H__
8
9 #include "mozilla/Attributes.h"
10 #include "gfxMatrix.h"
11 #include "nsCOMPtr.h"
12 #include "nsFrame.h"
13 #include "nsLiteralString.h"
14 #include "nsSVGPaintServerFrame.h"
15
16 class gfxPattern;
17 class nsIAtom;
18 class nsIContent;
19 class nsIFrame;
20 class nsIPresShell;
21 class nsStyleContext;
22
23 struct gfxRect;
24
25 namespace mozilla {
26 class nsSVGAnimatedTransformList;
27
28 namespace dom {
29 class SVGLinearGradientElement;
30 class SVGRadialGradientElement;
31 } // namespace dom
32 } // namespace mozilla
33
34 typedef nsSVGPaintServerFrame nsSVGGradientFrameBase;
35
36 /**
37 * Gradients can refer to other gradients. We create an nsSVGPaintingProperty
38 * with property type nsGkAtoms::href to track the referenced gradient.
39 */
40 class nsSVGGradientFrame : public nsSVGGradientFrameBase
41 {
42 protected:
43 nsSVGGradientFrame(nsStyleContext* aContext);
44
45 public:
46 NS_DECL_FRAMEARENA_HELPERS
47
48 // nsSVGPaintServerFrame methods:
49 virtual already_AddRefed<gfxPattern>
50 GetPaintServerPattern(nsIFrame *aSource,
51 const gfxMatrix& aContextMatrix,
52 nsStyleSVGPaint nsStyleSVG::*aFillOrStroke,
53 float aGraphicOpacity,
54 const gfxRect *aOverrideBounds) MOZ_OVERRIDE;
55
56 // nsIFrame interface:
57 virtual nsresult AttributeChanged(int32_t aNameSpaceID,
58 nsIAtom* aAttribute,
59 int32_t aModType) MOZ_OVERRIDE;
60
61 #ifdef DEBUG_FRAME_DUMP
62 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
63 {
64 return MakeFrameName(NS_LITERAL_STRING("SVGGradient"), aResult);
65 }
66 #endif // DEBUG
67
68 private:
69
70 // Parse our xlink:href and set up our nsSVGPaintingProperty if we
71 // reference another gradient and we don't have a property. Return
72 // the referenced gradient's frame if available, null otherwise.
73 nsSVGGradientFrame* GetReferencedGradient();
74
75 // Optionally get a stop frame (returns stop index/count)
76 void GetStopFrames(nsTArray<nsIFrame*>* aStopFrames);
77
78 const mozilla::nsSVGAnimatedTransformList* GetGradientTransformList(
79 nsIContent* aDefault);
80 // Will be singular for gradientUnits="objectBoundingBox" with an empty bbox.
81 gfxMatrix GetGradientTransform(nsIFrame *aSource,
82 const gfxRect *aOverrideBounds);
83
84 protected:
85 virtual bool GradientVectorLengthIsZero() = 0;
86 virtual already_AddRefed<gfxPattern> CreateGradient() = 0;
87
88 // Internal methods for handling referenced gradients
89 class AutoGradientReferencer;
90 nsSVGGradientFrame* GetReferencedGradientIfNotInUse();
91
92 // Accessors to lookup gradient attributes
93 uint16_t GetEnumValue(uint32_t aIndex, nsIContent *aDefault);
94 uint16_t GetEnumValue(uint32_t aIndex)
95 {
96 return GetEnumValue(aIndex, mContent);
97 }
98 uint16_t GetGradientUnits();
99 uint16_t GetSpreadMethod();
100
101 // Gradient-type-specific lookups since the length values differ between
102 // linear and radial gradients
103 virtual mozilla::dom::SVGLinearGradientElement * GetLinearGradientWithLength(
104 uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault);
105 virtual mozilla::dom::SVGRadialGradientElement * GetRadialGradientWithLength(
106 uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault);
107
108 // The frame our gradient is (currently) being applied to
109 nsIFrame* mSource;
110
111 private:
112 // Flag to mark this frame as "in use" during recursive calls along our
113 // gradient's reference chain so we can detect reference loops. See:
114 // http://www.w3.org/TR/SVG11/pservers.html#LinearGradientElementHrefAttribute
115 bool mLoopFlag;
116 // Gradients often don't reference other gradients, so here we cache
117 // the fact that that isn't happening.
118 bool mNoHRefURI;
119 };
120
121
122 // -------------------------------------------------------------------------
123 // Linear Gradients
124 // -------------------------------------------------------------------------
125
126 typedef nsSVGGradientFrame nsSVGLinearGradientFrameBase;
127
128 class nsSVGLinearGradientFrame : public nsSVGLinearGradientFrameBase
129 {
130 friend nsIFrame* NS_NewSVGLinearGradientFrame(nsIPresShell* aPresShell,
131 nsStyleContext* aContext);
132 protected:
133 nsSVGLinearGradientFrame(nsStyleContext* aContext) :
134 nsSVGLinearGradientFrameBase(aContext) {}
135
136 public:
137 NS_DECL_FRAMEARENA_HELPERS
138
139 // nsIFrame interface:
140 #ifdef DEBUG
141 virtual void Init(nsIContent* aContent,
142 nsIFrame* aParent,
143 nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
144 #endif
145
146 virtual nsIAtom* GetType() const MOZ_OVERRIDE; // frame type: nsGkAtoms::svgLinearGradientFrame
147
148 virtual nsresult AttributeChanged(int32_t aNameSpaceID,
149 nsIAtom* aAttribute,
150 int32_t aModType) MOZ_OVERRIDE;
151
152 #ifdef DEBUG_FRAME_DUMP
153 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
154 {
155 return MakeFrameName(NS_LITERAL_STRING("SVGLinearGradient"), aResult);
156 }
157 #endif // DEBUG
158
159 protected:
160 float GetLengthValue(uint32_t aIndex);
161 virtual mozilla::dom::SVGLinearGradientElement* GetLinearGradientWithLength(
162 uint32_t aIndex, mozilla::dom::SVGLinearGradientElement* aDefault) MOZ_OVERRIDE;
163 virtual bool GradientVectorLengthIsZero() MOZ_OVERRIDE;
164 virtual already_AddRefed<gfxPattern> CreateGradient() MOZ_OVERRIDE;
165 };
166
167 // -------------------------------------------------------------------------
168 // Radial Gradients
169 // -------------------------------------------------------------------------
170
171 typedef nsSVGGradientFrame nsSVGRadialGradientFrameBase;
172
173 class nsSVGRadialGradientFrame : public nsSVGRadialGradientFrameBase
174 {
175 friend nsIFrame* NS_NewSVGRadialGradientFrame(nsIPresShell* aPresShell,
176 nsStyleContext* aContext);
177 protected:
178 nsSVGRadialGradientFrame(nsStyleContext* aContext) :
179 nsSVGRadialGradientFrameBase(aContext) {}
180
181 public:
182 NS_DECL_FRAMEARENA_HELPERS
183
184 // nsIFrame interface:
185 #ifdef DEBUG
186 virtual void Init(nsIContent* aContent,
187 nsIFrame* aParent,
188 nsIFrame* aPrevInFlow) MOZ_OVERRIDE;
189 #endif
190
191 virtual nsIAtom* GetType() const MOZ_OVERRIDE; // frame type: nsGkAtoms::svgRadialGradientFrame
192
193 virtual nsresult AttributeChanged(int32_t aNameSpaceID,
194 nsIAtom* aAttribute,
195 int32_t aModType) MOZ_OVERRIDE;
196
197 #ifdef DEBUG_FRAME_DUMP
198 virtual nsresult GetFrameName(nsAString& aResult) const MOZ_OVERRIDE
199 {
200 return MakeFrameName(NS_LITERAL_STRING("SVGRadialGradient"), aResult);
201 }
202 #endif // DEBUG
203
204 protected:
205 float GetLengthValue(uint32_t aIndex);
206 float GetLengthValue(uint32_t aIndex, float aDefaultValue);
207 float GetLengthValueFromElement(uint32_t aIndex,
208 mozilla::dom::SVGRadialGradientElement& aElement);
209 virtual mozilla::dom::SVGRadialGradientElement* GetRadialGradientWithLength(
210 uint32_t aIndex, mozilla::dom::SVGRadialGradientElement* aDefault) MOZ_OVERRIDE;
211 virtual bool GradientVectorLengthIsZero() MOZ_OVERRIDE;
212 virtual already_AddRefed<gfxPattern> CreateGradient() MOZ_OVERRIDE;
213 };
214
215 #endif // __NS_SVGGRADIENTFRAME_H__
216

mercurial