|
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 |