/src/mozilla-central/dom/svg/nsSVGLength2.h
Line | Count | Source (jump to first uncovered line) |
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 "mozilla/dom/SVGLengthBinding.h" |
13 | | #include "nsCoord.h" |
14 | | #include "nsCycleCollectionParticipant.h" |
15 | | #include "nsError.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 SVGViewportElement; |
31 | | } // namespace dom |
32 | | } // namespace mozilla |
33 | | |
34 | | namespace mozilla { |
35 | | namespace dom { |
36 | | |
37 | | class UserSpaceMetrics |
38 | | { |
39 | | public: |
40 | 0 | 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 | | 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 | | class SVGElementMetrics : public UserSpaceMetrics |
55 | | { |
56 | | public: |
57 | | typedef mozilla::dom::SVGViewportElement SVGViewportElement; |
58 | | |
59 | | explicit SVGElementMetrics(nsSVGElement* aSVGElement, |
60 | | SVGViewportElement* aCtx = nullptr); |
61 | | |
62 | | virtual float GetEmLength() const override; |
63 | | virtual float GetExLength() const override; |
64 | | virtual float GetAxisLength(uint8_t aCtxType) const override; |
65 | | |
66 | | private: |
67 | | bool EnsureCtx() const; |
68 | | |
69 | | nsSVGElement* mSVGElement; |
70 | | mutable SVGViewportElement* mCtx; |
71 | | }; |
72 | | |
73 | | class NonSVGFrameUserSpaceMetrics : public UserSpaceMetricsWithSize |
74 | | { |
75 | | public: |
76 | | explicit NonSVGFrameUserSpaceMetrics(nsIFrame* aFrame); |
77 | | |
78 | | virtual float GetEmLength() const override; |
79 | | virtual float GetExLength() const override; |
80 | | virtual gfx::Size GetSize() const override; |
81 | | |
82 | | private: |
83 | | nsIFrame* mFrame; |
84 | | }; |
85 | | |
86 | | } // namespace dom |
87 | | } // namespace mozilla |
88 | | |
89 | | class nsSVGLength2 |
90 | | { |
91 | | friend class mozilla::dom::SVGAnimatedLength; |
92 | | friend class mozilla::DOMSVGLength; |
93 | | typedef mozilla::dom::UserSpaceMetrics UserSpaceMetrics; |
94 | | typedef mozilla::dom::SVGViewportElement SVGViewportElement; |
95 | | |
96 | | public: |
97 | | void Init(uint8_t aCtxType = SVGContentUtils::XY, |
98 | | uint8_t aAttrEnum = 0xff, |
99 | | float aValue = 0, |
100 | | uint8_t aUnitType = |
101 | 0 | mozilla::dom::SVGLength_Binding::SVG_LENGTHTYPE_NUMBER) { |
102 | 0 | mAnimVal = mBaseVal = aValue; |
103 | 0 | mSpecifiedUnitType = aUnitType; |
104 | 0 | mAttrEnum = aAttrEnum; |
105 | 0 | mCtxType = aCtxType; |
106 | 0 | mIsAnimated = false; |
107 | 0 | mIsBaseSet = false; |
108 | 0 | } |
109 | | |
110 | 0 | nsSVGLength2& operator=(const nsSVGLength2& aLength) { |
111 | 0 | mBaseVal = aLength.mBaseVal; |
112 | 0 | mAnimVal = aLength.mAnimVal; |
113 | 0 | mSpecifiedUnitType = aLength.mSpecifiedUnitType; |
114 | 0 | mIsAnimated = aLength.mIsAnimated; |
115 | 0 | mIsBaseSet = aLength.mIsBaseSet; |
116 | 0 | return *this; |
117 | 0 | } |
118 | | |
119 | | nsresult SetBaseValueString(const nsAString& aValue, |
120 | | nsSVGElement *aSVGElement, |
121 | | bool aDoSetAttr); |
122 | | void GetBaseValueString(nsAString& aValue) const; |
123 | | void GetAnimValueString(nsAString& aValue) const; |
124 | | |
125 | | float GetBaseValue(nsSVGElement* aSVGElement) const |
126 | 0 | { return mBaseVal * GetPixelsPerUnit(aSVGElement, mSpecifiedUnitType); } |
127 | | |
128 | | float GetAnimValue(nsSVGElement* aSVGElement) const |
129 | 0 | { return mAnimVal * GetPixelsPerUnit(aSVGElement, mSpecifiedUnitType); } |
130 | | float GetAnimValue(nsIFrame* aFrame) const |
131 | 0 | { return mAnimVal * GetPixelsPerUnit(aFrame, mSpecifiedUnitType); } |
132 | | float GetAnimValue(SVGViewportElement* aCtx) const |
133 | 0 | { return mAnimVal * GetPixelsPerUnit(aCtx, mSpecifiedUnitType); } |
134 | | float GetAnimValue(const UserSpaceMetrics& aMetrics) const |
135 | 0 | { return mAnimVal * GetPixelsPerUnit(aMetrics, mSpecifiedUnitType); } |
136 | | |
137 | 0 | uint8_t GetCtxType() const { return mCtxType; } |
138 | 0 | uint8_t GetSpecifiedUnitType() const { return mSpecifiedUnitType; } |
139 | | bool IsPercentage() const |
140 | 0 | { return mSpecifiedUnitType == |
141 | 0 | mozilla::dom::SVGLength_Binding::SVG_LENGTHTYPE_PERCENTAGE; } |
142 | 0 | float GetAnimValInSpecifiedUnits() const { return mAnimVal; } |
143 | 0 | float GetBaseValInSpecifiedUnits() const { return mBaseVal; } |
144 | | |
145 | | float GetBaseValue(SVGViewportElement* aCtx) const |
146 | 0 | { return mBaseVal * GetPixelsPerUnit(aCtx, mSpecifiedUnitType); } |
147 | | |
148 | 0 | bool HasBaseVal() const { |
149 | 0 | return mIsBaseSet; |
150 | 0 | } |
151 | | // Returns true if the animated value of this length has been explicitly |
152 | | // set (either by animation, or by taking on the base value which has been |
153 | | // explicitly set by markup or a DOM call), false otherwise. |
154 | | // If this returns false, the animated value is still valid, that is, |
155 | | // usable, and represents the default base value of the attribute. |
156 | | bool IsExplicitlySet() const |
157 | 0 | { return mIsAnimated || mIsBaseSet; } |
158 | | |
159 | | already_AddRefed<mozilla::dom::SVGAnimatedLength> |
160 | | ToDOMAnimatedLength(nsSVGElement* aSVGElement); |
161 | | |
162 | | mozilla::UniquePtr<nsISMILAttr> ToSMILAttr(nsSVGElement* aSVGElement); |
163 | | |
164 | | private: |
165 | | float mAnimVal; |
166 | | float mBaseVal; |
167 | | uint8_t mSpecifiedUnitType; |
168 | | uint8_t mAttrEnum; // element specified tracking for attribute |
169 | | uint8_t mCtxType; // X, Y or Unspecified |
170 | | bool mIsAnimated:1; |
171 | | bool mIsBaseSet:1; |
172 | | |
173 | | // These APIs returns the number of user-unit pixels per unit of the |
174 | | // given type, in a given context (frame/element/etc). |
175 | | float GetPixelsPerUnit(nsIFrame* aFrame, uint8_t aUnitType) const; |
176 | | float GetPixelsPerUnit(const UserSpaceMetrics& aMetrics, uint8_t aUnitType) const; |
177 | | float GetPixelsPerUnit(nsSVGElement* aSVGElement, uint8_t aUnitType) const; |
178 | | float GetPixelsPerUnit(SVGViewportElement* aCtx, uint8_t aUnitType) const; |
179 | | |
180 | | // SetBaseValue and SetAnimValue set the value in user units. This may fail |
181 | | // if unit conversion fails e.g. conversion to ex or em units where the |
182 | | // font-size is 0. |
183 | | // SetBaseValueInSpecifiedUnits and SetAnimValueInSpecifiedUnits do not |
184 | | // perform unit conversion and are therefore infallible. |
185 | | nsresult SetBaseValue(float aValue, nsSVGElement *aSVGElement, |
186 | | bool aDoSetAttr); |
187 | | void SetBaseValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement, |
188 | | bool aDoSetAttr); |
189 | | nsresult SetAnimValue(float aValue, nsSVGElement *aSVGElement); |
190 | | void SetAnimValueInSpecifiedUnits(float aValue, nsSVGElement *aSVGElement); |
191 | | nsresult NewValueSpecifiedUnits(uint16_t aUnitType, float aValue, |
192 | | nsSVGElement *aSVGElement); |
193 | | nsresult ConvertToSpecifiedUnits(uint16_t aUnitType, nsSVGElement *aSVGElement); |
194 | | nsresult ToDOMBaseVal(mozilla::DOMSVGLength **aResult, nsSVGElement* aSVGElement); |
195 | | nsresult ToDOMAnimVal(mozilla::DOMSVGLength **aResult, nsSVGElement* aSVGElement); |
196 | | |
197 | | public: |
198 | | struct SMILLength : public nsISMILAttr |
199 | | { |
200 | | public: |
201 | | SMILLength(nsSVGLength2* aVal, nsSVGElement *aSVGElement) |
202 | 0 | : mVal(aVal), mSVGElement(aSVGElement) {} |
203 | | |
204 | | // These will stay alive because a nsISMILAttr only lives as long |
205 | | // as the Compositing step, and DOM elements don't get a chance to |
206 | | // die during that. |
207 | | nsSVGLength2* mVal; |
208 | | nsSVGElement* mSVGElement; |
209 | | |
210 | | // nsISMILAttr methods |
211 | | virtual nsresult ValueFromString(const nsAString& aStr, |
212 | | const mozilla::dom::SVGAnimationElement* aSrcElement, |
213 | | nsSMILValue &aValue, |
214 | | bool& aPreventCachingOfSandwich) const override; |
215 | | virtual nsSMILValue GetBaseValue() const override; |
216 | | virtual void ClearAnimValue() override; |
217 | | virtual nsresult SetAnimValue(const nsSMILValue& aValue) override; |
218 | | }; |
219 | | }; |
220 | | |
221 | | #endif // __NS_SVGLENGTH2_H__ |