Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef __NS_SVGVIEWBOX_H__
8 : #define __NS_SVGVIEWBOX_H__
9 :
10 : #include "nsAutoPtr.h"
11 : #include "nsCycleCollectionParticipant.h"
12 : #include "nsError.h"
13 : #include "mozilla/dom/SVGAnimatedRect.h"
14 : #include "mozilla/dom/SVGIRect.h"
15 : #include "nsISMILAttr.h"
16 : #include "nsSVGElement.h"
17 : #include "mozilla/Attributes.h"
18 : #include "mozilla/UniquePtr.h"
19 : #include "nsSVGAttrTearoffTable.h"
20 :
21 : class nsSMILValue;
22 :
23 : namespace mozilla {
24 : namespace dom {
25 : class SVGAnimationElement;
26 : } // namespace dom
27 : } // namespace mozilla
28 :
29 : struct nsSVGViewBoxRect
30 : {
31 : float x, y;
32 : float width, height;
33 : bool none;
34 :
35 38 : nsSVGViewBoxRect() : none(true) {}
36 118 : nsSVGViewBoxRect(float aX, float aY, float aWidth, float aHeight) :
37 118 : x(aX), y(aY), width(aWidth), height(aHeight), none(false) {}
38 421 : nsSVGViewBoxRect(const nsSVGViewBoxRect& rhs) :
39 421 : x(rhs.x), y(rhs.y), width(rhs.width), height(rhs.height), none(rhs.none) {}
40 : bool operator==(const nsSVGViewBoxRect& aOther) const;
41 :
42 : static nsresult FromString(const nsAString& aStr, nsSVGViewBoxRect *aViewBox);
43 : };
44 :
45 22 : class nsSVGViewBox
46 : {
47 : public:
48 :
49 : void Init();
50 :
51 : /**
52 : * Returns true if the corresponding "viewBox" attribute defined a rectangle
53 : * with finite values and nonnegative width/height.
54 : * Returns false if the viewBox was set to an invalid
55 : * string, or if any of the four rect values were too big to store in a
56 : * float, or the width/height are negative.
57 : */
58 : bool HasRect() const;
59 :
60 : /**
61 : * Returns true if the corresponding "viewBox" attribute either defined a
62 : * rectangle with finite values or the special "none" value.
63 : */
64 0 : bool IsExplicitlySet() const
65 : {
66 0 : if (mAnimVal || mHasBaseVal) {
67 0 : const nsSVGViewBoxRect& rect = GetAnimValue();
68 0 : return rect.none || (rect.width >= 0 && rect.height >= 0);
69 : }
70 0 : return false;
71 : }
72 :
73 0 : const nsSVGViewBoxRect& GetBaseValue() const
74 0 : { return mBaseVal; }
75 : void SetBaseValue(const nsSVGViewBoxRect& aRect,
76 : nsSVGElement *aSVGElement);
77 505 : const nsSVGViewBoxRect& GetAnimValue() const
78 505 : { return mAnimVal ? *mAnimVal : mBaseVal; }
79 : void SetAnimValue(const nsSVGViewBoxRect& aRect,
80 : nsSVGElement *aSVGElement);
81 :
82 : nsresult SetBaseValueString(const nsAString& aValue,
83 : nsSVGElement *aSVGElement,
84 : bool aDoSetAttr);
85 : void GetBaseValueString(nsAString& aValue) const;
86 :
87 : already_AddRefed<mozilla::dom::SVGAnimatedRect>
88 : ToSVGAnimatedRect(nsSVGElement *aSVGElement);
89 :
90 : already_AddRefed<mozilla::dom::SVGIRect>
91 : ToDOMBaseVal(nsSVGElement* aSVGElement);
92 :
93 : already_AddRefed<mozilla::dom::SVGIRect>
94 : ToDOMAnimVal(nsSVGElement* aSVGElement);
95 :
96 : mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(nsSVGElement* aSVGElement);
97 :
98 : private:
99 : nsSVGViewBoxRect mBaseVal;
100 : nsAutoPtr<nsSVGViewBoxRect> mAnimVal;
101 : bool mHasBaseVal;
102 :
103 : public:
104 : struct DOMBaseVal final : public mozilla::dom::SVGIRect
105 : {
106 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
107 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMBaseVal)
108 :
109 0 : DOMBaseVal(nsSVGViewBox *aVal, nsSVGElement *aSVGElement)
110 0 : : mozilla::dom::SVGIRect()
111 : , mVal(aVal)
112 0 : , mSVGElement(aSVGElement)
113 0 : {}
114 :
115 : nsSVGViewBox* mVal; // kept alive because it belongs to content
116 : RefPtr<nsSVGElement> mSVGElement;
117 :
118 0 : float X() const override final
119 : {
120 0 : return mVal->GetBaseValue().x;
121 : }
122 :
123 0 : float Y() const override final
124 : {
125 0 : return mVal->GetBaseValue().y;
126 : }
127 :
128 0 : float Width() const override final
129 : {
130 0 : return mVal->GetBaseValue().width;
131 : }
132 :
133 0 : float Height() const override final
134 : {
135 0 : return mVal->GetBaseValue().height;
136 : }
137 :
138 : void SetX(float aX, mozilla::ErrorResult& aRv) final override;
139 : void SetY(float aY, mozilla::ErrorResult& aRv) final override;
140 : void SetWidth(float aWidth, mozilla::ErrorResult& aRv) final override;
141 : void SetHeight(float aHeight, mozilla::ErrorResult& aRv) final override;
142 :
143 0 : virtual nsIContent* GetParentObject() const override
144 : {
145 0 : return mSVGElement;
146 : }
147 :
148 : private:
149 : virtual ~DOMBaseVal();
150 : };
151 :
152 : struct DOMAnimVal final : public mozilla::dom::SVGIRect
153 : {
154 : NS_DECL_CYCLE_COLLECTING_ISUPPORTS
155 0 : NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMAnimVal)
156 :
157 0 : DOMAnimVal(nsSVGViewBox *aVal, nsSVGElement *aSVGElement)
158 0 : : mozilla::dom::SVGIRect()
159 : , mVal(aVal)
160 0 : , mSVGElement(aSVGElement)
161 0 : {}
162 :
163 : nsSVGViewBox* mVal; // kept alive because it belongs to content
164 : RefPtr<nsSVGElement> mSVGElement;
165 :
166 : // Script may have modified animation parameters or timeline -- DOM getters
167 : // need to flush any resample requests to reflect these modifications.
168 0 : float X() const override final
169 : {
170 0 : mSVGElement->FlushAnimations();
171 0 : return mVal->GetAnimValue().x;
172 : }
173 :
174 0 : float Y() const override final
175 : {
176 0 : mSVGElement->FlushAnimations();
177 0 : return mVal->GetAnimValue().y;
178 : }
179 :
180 0 : float Width() const override final
181 : {
182 0 : mSVGElement->FlushAnimations();
183 0 : return mVal->GetAnimValue().width;
184 : }
185 :
186 0 : float Height() const override final
187 : {
188 0 : mSVGElement->FlushAnimations();
189 0 : return mVal->GetAnimValue().height;
190 : }
191 :
192 0 : void SetX(float aX, mozilla::ErrorResult& aRv) final override
193 : {
194 0 : aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
195 0 : }
196 :
197 0 : void SetY(float aY, mozilla::ErrorResult& aRv) final override
198 : {
199 0 : aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
200 0 : }
201 :
202 0 : void SetWidth(float aWidth, mozilla::ErrorResult& aRv) final override
203 : {
204 0 : aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
205 0 : }
206 :
207 0 : void SetHeight(float aHeight, mozilla::ErrorResult& aRv) final override
208 : {
209 0 : aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
210 0 : }
211 :
212 0 : virtual nsIContent* GetParentObject() const override
213 : {
214 0 : return mSVGElement;
215 : }
216 :
217 : private:
218 : virtual ~DOMAnimVal();
219 :
220 : };
221 :
222 0 : struct SMILViewBox : public nsISMILAttr
223 : {
224 : public:
225 0 : SMILViewBox(nsSVGViewBox* aVal, nsSVGElement* aSVGElement)
226 0 : : mVal(aVal), mSVGElement(aSVGElement) {}
227 :
228 : // These will stay alive because a nsISMILAttr only lives as long
229 : // as the Compositing step, and DOM elements don't get a chance to
230 : // die during that.
231 : nsSVGViewBox* mVal;
232 : nsSVGElement* mSVGElement;
233 :
234 : // nsISMILAttr methods
235 : virtual nsresult ValueFromString(const nsAString& aStr,
236 : const mozilla::dom::SVGAnimationElement* aSrcElement,
237 : nsSMILValue& aValue,
238 : bool& aPreventCachingOfSandwich) const override;
239 : virtual nsSMILValue GetBaseValue() const override;
240 : virtual void ClearAnimValue() override;
241 : virtual nsresult SetAnimValue(const nsSMILValue& aValue) override;
242 : };
243 :
244 : static nsSVGAttrTearoffTable<nsSVGViewBox, mozilla::dom::SVGAnimatedRect>
245 : sSVGAnimatedRectTearoffTable;
246 : };
247 :
248 : #endif // __NS_SVGVIEWBOX_H__
|