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_SVGLENGTH2_H__
8 : #define __NS_SVGLENGTH2_H__
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "mozilla/UniquePtr.h"
12 : #include "nsCoord.h"
13 : #include "nsCycleCollectionParticipant.h"
14 : #include "nsError.h"
15 : #include "nsIDOMSVGLength.h"
16 : #include "nsISMILAttr.h"
17 : #include "nsMathUtils.h"
18 : #include "nsSVGElement.h"
19 : #include "SVGContentUtils.h"
20 : #include "mozilla/gfx/Rect.h"
21 :
22 : class nsIFrame;
23 : class nsSMILValue;
24 :
25 : namespace mozilla {
26 : class DOMSVGLength;
27 : namespace dom {
28 : class SVGAnimatedLength;
29 : class SVGAnimationElement;
30 : class SVGSVGElement;
31 : } // namespace dom
32 : } // namespace mozilla
33 :
34 : namespace mozilla {
35 : namespace dom {
36 :
37 1489 : class UserSpaceMetrics
38 : {
39 : public:
40 1489 : virtual ~UserSpaceMetrics() {}
41 :
42 : virtual float GetEmLength() const = 0;
43 : virtual float GetExLength() const = 0;
44 : virtual float GetAxisLength(uint8_t aCtxType) const = 0;
45 : };
46 :
47 0 : class UserSpaceMetricsWithSize : public UserSpaceMetrics
48 : {
49 : public:
50 : virtual gfx::Size GetSize() const = 0;
51 : virtual float GetAxisLength(uint8_t aCtxType) const override;
52 : };
53 :
54 1489 : class SVGElementMetrics : public UserSpaceMetrics
55 : {
56 : public:
57 : explicit SVGElementMetrics(nsSVGElement* aSVGElement,
58 : mozilla::dom::SVGSVGElement* aCtx = nullptr);
59 :
60 : virtual float GetEmLength() const override;
61 : virtual float GetExLength() const override;
62 : virtual float GetAxisLength(uint8_t aCtxType) const override;
63 :
64 : private:
65 : bool EnsureCtx() const;
66 :
67 : nsSVGElement* mSVGElement;
68 : mutable mozilla::dom::SVGSVGElement* mCtx;
69 : };
70 :
71 0 : class NonSVGFrameUserSpaceMetrics : public UserSpaceMetricsWithSize
72 : {
73 : public:
74 : explicit NonSVGFrameUserSpaceMetrics(nsIFrame* aFrame);
75 :
76 : virtual float GetEmLength() const override;
77 : virtual float GetExLength() const override;
78 : virtual gfx::Size GetSize() const override;
79 :
80 : private:
81 : nsIFrame* mFrame;
82 : };
83 :
84 : } // namespace dom
85 : } // namespace mozilla
86 :
87 : class nsSVGLength2
88 : {
89 : friend class mozilla::dom::SVGAnimatedLength;
90 : friend class mozilla::DOMSVGLength;
91 : typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics;
92 : public:
93 300 : void Init(uint8_t aCtxType = SVGContentUtils::XY,
94 : uint8_t aAttrEnum = 0xff,
95 : float aValue = 0,
96 : uint8_t aUnitType = nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER) {
97 300 : mAnimVal = mBaseVal = aValue;
98 300 : mSpecifiedUnitType = aUnitType;
99 300 : mAttrEnum = aAttrEnum;
100 300 : mCtxType = aCtxType;
101 300 : mIsAnimated = false;
102 300 : mIsBaseSet = false;
103 300 : }
104 :
105 0 : nsSVGLength2& operator=(const nsSVGLength2& aLength) {
106 0 : mBaseVal = aLength.mBaseVal;
107 0 : mAnimVal = aLength.mAnimVal;
108 0 : mSpecifiedUnitType = aLength.mSpecifiedUnitType;
109 0 : mIsAnimated = aLength.mIsAnimated;
110 0 : mIsBaseSet = aLength.mIsBaseSet;
111 0 : return *this;
112 : }
113 :
114 : nsresult SetBaseValueString(const nsAString& aValue,
115 : nsSVGElement *aSVGElement,
116 : bool aDoSetAttr);
117 : void GetBaseValueString(nsAString& aValue) const;
118 : void GetAnimValueString(nsAString& aValue) const;
119 :
120 0 : float GetBaseValue(nsSVGElement* aSVGElement) const
121 0 : { return mBaseVal / GetUnitScaleFactor(aSVGElement, mSpecifiedUnitType); }
122 :
123 236 : float GetAnimValue(nsSVGElement* aSVGElement) const
124 236 : { return mAnimVal / GetUnitScaleFactor(aSVGElement, mSpecifiedUnitType); }
125 0 : float GetAnimValue(nsIFrame* aFrame) const
126 0 : { return mAnimVal / GetUnitScaleFactor(aFrame, mSpecifiedUnitType); }
127 1253 : float GetAnimValue(mozilla::dom::SVGSVGElement* aCtx) const
128 1253 : { return mAnimVal / GetUnitScaleFactor(aCtx, mSpecifiedUnitType); }
129 0 : float GetAnimValue(const UserSpaceMetrics& aMetrics) const
130 0 : { return mAnimVal / GetUnitScaleFactor(aMetrics, mSpecifiedUnitType); }
131 :
132 0 : uint8_t GetCtxType() const { return mCtxType; }
133 308 : uint8_t GetSpecifiedUnitType() const { return mSpecifiedUnitType; }
134 1228 : bool IsPercentage() const
135 1228 : { return mSpecifiedUnitType == nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE; }
136 32 : float GetAnimValInSpecifiedUnits() const { return mAnimVal; }
137 0 : float GetBaseValInSpecifiedUnits() const { return mBaseVal; }
138 :
139 : float GetBaseValue(mozilla::dom::SVGSVGElement* aCtx) const
140 : { return mBaseVal / GetUnitScaleFactor(aCtx, mSpecifiedUnitType); }
141 :
142 41 : bool HasBaseVal() const {
143 41 : return mIsBaseSet;
144 : }
145 : // Returns true if the animated value of this length has been explicitly
146 : // set (either by animation, or by taking on the base value which has been
147 : // explicitly set by markup or a DOM call), false otherwise.
148 : // If this returns false, the animated value is still valid, that is,
149 : // useable, and represents the default base value of the attribute.
150 118 : bool IsExplicitlySet() const
151 118 : { return mIsAnimated || mIsBaseSet; }
152 :
153 : already_AddRefed<mozilla::dom::SVGAnimatedLength>
154 : ToDOMAnimatedLength(nsSVGElement* aSVGElement);
155 :
156 : mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(nsSVGElement* aSVGElement);
157 :
158 : private:
159 : float mAnimVal;
160 : float mBaseVal;
161 : uint8_t mSpecifiedUnitType;
162 : uint8_t mAttrEnum; // element specified tracking for attribute
163 : uint8_t mCtxType; // X, Y or Unspecified
164 : bool mIsAnimated:1;
165 : bool mIsBaseSet:1;
166 :
167 : float GetUnitScaleFactor(nsIFrame *aFrame, uint8_t aUnitType) const;
168 : float GetUnitScaleFactor(const UserSpaceMetrics& aMetrics, uint8_t aUnitType) const;
169 : float GetUnitScaleFactor(nsSVGElement *aSVGElement, uint8_t aUnitType) const;
170 : float GetUnitScaleFactor(mozilla::dom::SVGSVGElement *aCtx, uint8_t aUnitType) const;
171 :
172 : // SetBaseValue and SetAnimValue set the value in user units
173 : void SetBaseValue(float aValue, nsSVGElement *aSVGElement, bool aDoSetAttr);
174 : void SetBaseValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement,
175 : bool aDoSetAttr);
176 : void SetAnimValue(float aValue, nsSVGElement *aSVGElement);
177 : void SetAnimValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement);
178 : nsresult NewValueSpecifiedUnits(uint16_t aUnitType, float aValue,
179 : nsSVGElement *aSVGElement);
180 : nsresult ConvertToSpecifiedUnits(uint16_t aUnitType, nsSVGElement *aSVGElement);
181 : nsresult ToDOMBaseVal(mozilla::DOMSVGLength **aResult, nsSVGElement* aSVGElement);
182 : nsresult ToDOMAnimVal(mozilla::DOMSVGLength **aResult, nsSVGElement* aSVGElement);
183 :
184 : public:
185 0 : struct SMILLength : public nsISMILAttr
186 : {
187 : public:
188 0 : SMILLength(nsSVGLength2* aVal, nsSVGElement *aSVGElement)
189 0 : : mVal(aVal), mSVGElement(aSVGElement) {}
190 :
191 : // These will stay alive because a nsISMILAttr only lives as long
192 : // as the Compositing step, and DOM elements don't get a chance to
193 : // die during that.
194 : nsSVGLength2* mVal;
195 : nsSVGElement* mSVGElement;
196 :
197 : // nsISMILAttr methods
198 : virtual nsresult ValueFromString(const nsAString& aStr,
199 : const mozilla::dom::SVGAnimationElement* aSrcElement,
200 : nsSMILValue &aValue,
201 : bool& aPreventCachingOfSandwich) const override;
202 : virtual nsSMILValue GetBaseValue() const override;
203 : virtual void ClearAnimValue() override;
204 : virtual nsresult SetAnimValue(const nsSMILValue& aValue) override;
205 : };
206 : };
207 :
208 : #endif // __NS_SVGLENGTH2_H__
|