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