/src/mozilla-central/layout/style/StyleAnimationValue.cpp
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 | | /* Utilities for animation of computed style values */ |
8 | | |
9 | | #include "mozilla/StyleAnimationValue.h" |
10 | | |
11 | | #include "mozilla/ArrayUtils.h" |
12 | | #include "mozilla/MathAlgorithms.h" |
13 | | #include "mozilla/ServoBindings.h" |
14 | | #include "mozilla/ServoStyleSet.h" |
15 | | #include "mozilla/Tuple.h" |
16 | | #include "mozilla/UniquePtr.h" |
17 | | #include "nsAutoPtr.h" |
18 | | #include "nsCOMArray.h" |
19 | | #include "nsString.h" |
20 | | #include "mozilla/ComputedStyle.h" |
21 | | #include "nsComputedDOMStyle.h" |
22 | | #include "nsCSSPseudoElements.h" |
23 | | #include "mozilla/dom/Element.h" |
24 | | #include "mozilla/FloatingPoint.h" |
25 | | #include "mozilla/Likely.h" |
26 | | #include "mozilla/ServoBindings.h" // RawServoDeclarationBlock |
27 | | #include "mozilla/ServoCSSParser.h" |
28 | | #include "gfxMatrix.h" |
29 | | #include "gfxQuaternion.h" |
30 | | #include "nsIDocument.h" |
31 | | #include "nsIFrame.h" |
32 | | #include "gfx2DGlue.h" |
33 | | #include "mozilla/ComputedStyleInlines.h" |
34 | | |
35 | | using namespace mozilla; |
36 | | using namespace mozilla::css; |
37 | | using namespace mozilla::gfx; |
38 | | using nsStyleTransformMatrix::Decompose2DMatrix; |
39 | | using nsStyleTransformMatrix::Decompose3DMatrix; |
40 | | using nsStyleTransformMatrix::ShearType; |
41 | | |
42 | | |
43 | | static already_AddRefed<nsCSSValue::Array> |
44 | | AppendFunction(nsCSSKeyword aTransformFunction) |
45 | 0 | { |
46 | 0 | uint32_t nargs; |
47 | 0 | switch (aTransformFunction) { |
48 | 0 | case eCSSKeyword_matrix3d: |
49 | 0 | nargs = 16; |
50 | 0 | break; |
51 | 0 | case eCSSKeyword_matrix: |
52 | 0 | nargs = 6; |
53 | 0 | break; |
54 | 0 | case eCSSKeyword_rotate3d: |
55 | 0 | nargs = 4; |
56 | 0 | break; |
57 | 0 | case eCSSKeyword_interpolatematrix: |
58 | 0 | case eCSSKeyword_accumulatematrix: |
59 | 0 | case eCSSKeyword_translate3d: |
60 | 0 | case eCSSKeyword_scale3d: |
61 | 0 | nargs = 3; |
62 | 0 | break; |
63 | 0 | case eCSSKeyword_translate: |
64 | 0 | case eCSSKeyword_skew: |
65 | 0 | case eCSSKeyword_scale: |
66 | 0 | nargs = 2; |
67 | 0 | break; |
68 | 0 | default: |
69 | 0 | NS_ERROR("must be a transform function"); |
70 | 0 | MOZ_FALLTHROUGH; |
71 | 0 | case eCSSKeyword_translatex: |
72 | 0 | case eCSSKeyword_translatey: |
73 | 0 | case eCSSKeyword_translatez: |
74 | 0 | case eCSSKeyword_scalex: |
75 | 0 | case eCSSKeyword_scaley: |
76 | 0 | case eCSSKeyword_scalez: |
77 | 0 | case eCSSKeyword_skewx: |
78 | 0 | case eCSSKeyword_skewy: |
79 | 0 | case eCSSKeyword_rotate: |
80 | 0 | case eCSSKeyword_rotatex: |
81 | 0 | case eCSSKeyword_rotatey: |
82 | 0 | case eCSSKeyword_rotatez: |
83 | 0 | case eCSSKeyword_perspective: |
84 | 0 | nargs = 1; |
85 | 0 | break; |
86 | 0 | } |
87 | 0 | |
88 | 0 | RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(nargs + 1); |
89 | 0 | arr->Item(0).SetIntValue(aTransformFunction, eCSSUnit_Enumerated); |
90 | 0 |
|
91 | 0 | return arr.forget(); |
92 | 0 | } |
93 | | |
94 | | |
95 | | |
96 | | // AnimationValue Implementation |
97 | | |
98 | | bool |
99 | | AnimationValue::operator==(const AnimationValue& aOther) const |
100 | 0 | { |
101 | 0 | if (mServo && aOther.mServo) { |
102 | 0 | return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo); |
103 | 0 | } |
104 | 0 | if (!mServo && !aOther.mServo) { |
105 | 0 | return true; |
106 | 0 | } |
107 | 0 | return false; |
108 | 0 | } |
109 | | |
110 | | bool |
111 | | AnimationValue::operator!=(const AnimationValue& aOther) const |
112 | 0 | { |
113 | 0 | return !operator==(aOther); |
114 | 0 | } |
115 | | |
116 | | float |
117 | | AnimationValue::GetOpacity() const |
118 | 0 | { |
119 | 0 | MOZ_ASSERT(mServo); |
120 | 0 | return Servo_AnimationValue_GetOpacity(mServo); |
121 | 0 | } |
122 | | |
123 | | already_AddRefed<const nsCSSValueSharedList> |
124 | | AnimationValue::GetTransformList() const |
125 | 0 | { |
126 | 0 | MOZ_ASSERT(mServo); |
127 | 0 |
|
128 | 0 | RefPtr<nsCSSValueSharedList> transform; |
129 | 0 | Servo_AnimationValue_GetTransform(mServo, &transform); |
130 | 0 | return transform.forget(); |
131 | 0 | } |
132 | | |
133 | | Size |
134 | | AnimationValue::GetScaleValue(const nsIFrame* aFrame) const |
135 | 0 | { |
136 | 0 | MOZ_ASSERT(mServo); |
137 | 0 | RefPtr<nsCSSValueSharedList> list; |
138 | 0 | Servo_AnimationValue_GetTransform(mServo, &list); |
139 | 0 | return nsStyleTransformMatrix::GetScaleValue(list, aFrame); |
140 | 0 | } |
141 | | |
142 | | void |
143 | | AnimationValue::SerializeSpecifiedValue(nsCSSPropertyID aProperty, |
144 | | nsAString& aString) const |
145 | 0 | { |
146 | 0 | MOZ_ASSERT(mServo); |
147 | 0 | Servo_AnimationValue_Serialize(mServo, aProperty, &aString); |
148 | 0 | } |
149 | | |
150 | | bool |
151 | | AnimationValue::IsInterpolableWith(nsCSSPropertyID aProperty, |
152 | | const AnimationValue& aToValue) const |
153 | 0 | { |
154 | 0 | if (IsNull() || aToValue.IsNull()) { |
155 | 0 | return false; |
156 | 0 | } |
157 | 0 | |
158 | 0 | MOZ_ASSERT(mServo); |
159 | 0 | MOZ_ASSERT(aToValue.mServo); |
160 | 0 | return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo); |
161 | 0 | } |
162 | | |
163 | | double |
164 | | AnimationValue::ComputeDistance(nsCSSPropertyID aProperty, |
165 | | const AnimationValue& aOther, |
166 | | ComputedStyle* aComputedStyle) const |
167 | 0 | { |
168 | 0 | if (IsNull() || aOther.IsNull()) { |
169 | 0 | return 0.0; |
170 | 0 | } |
171 | 0 | |
172 | 0 | MOZ_ASSERT(mServo); |
173 | 0 | MOZ_ASSERT(aOther.mServo); |
174 | 0 |
|
175 | 0 | double distance = |
176 | 0 | Servo_AnimationValues_ComputeDistance(mServo, aOther.mServo); |
177 | 0 | return distance < 0.0 |
178 | 0 | ? 0.0 |
179 | 0 | : distance; |
180 | 0 | } |
181 | | |
182 | | /* static */ AnimationValue |
183 | | AnimationValue::FromString(nsCSSPropertyID aProperty, |
184 | | const nsAString& aValue, |
185 | | Element* aElement) |
186 | 0 | { |
187 | 0 | MOZ_ASSERT(aElement); |
188 | 0 |
|
189 | 0 | AnimationValue result; |
190 | 0 |
|
191 | 0 | nsCOMPtr<nsIDocument> doc = aElement->GetComposedDoc(); |
192 | 0 | if (!doc) { |
193 | 0 | return result; |
194 | 0 | } |
195 | 0 | |
196 | 0 | nsCOMPtr<nsIPresShell> shell = doc->GetShell(); |
197 | 0 | if (!shell) { |
198 | 0 | return result; |
199 | 0 | } |
200 | 0 | |
201 | 0 | // GetComputedStyle() flushes style, so we shouldn't assume that any |
202 | 0 | // non-owning references we have are still valid. |
203 | 0 | RefPtr<ComputedStyle> computedStyle = |
204 | 0 | nsComputedDOMStyle::GetComputedStyle(aElement, nullptr); |
205 | 0 | MOZ_ASSERT(computedStyle); |
206 | 0 |
|
207 | 0 | RefPtr<RawServoDeclarationBlock> declarations = |
208 | 0 | ServoCSSParser::ParseProperty(aProperty, aValue, |
209 | 0 | ServoCSSParser::GetParsingEnvironment(doc)); |
210 | 0 |
|
211 | 0 | if (!declarations) { |
212 | 0 | return result; |
213 | 0 | } |
214 | 0 | |
215 | 0 | result.mServo = shell->StyleSet()-> |
216 | 0 | ComputeAnimationValue(aElement, declarations, computedStyle); |
217 | 0 | return result; |
218 | 0 | } |
219 | | |
220 | | /* static */ AnimationValue |
221 | | AnimationValue::Opacity(float aOpacity) |
222 | 0 | { |
223 | 0 | AnimationValue result; |
224 | 0 | result.mServo = Servo_AnimationValue_Opacity(aOpacity).Consume(); |
225 | 0 | return result; |
226 | 0 | } |
227 | | |
228 | | /* static */ AnimationValue |
229 | | AnimationValue::Transform(nsCSSValueSharedList& aList) |
230 | 0 | { |
231 | 0 | AnimationValue result; |
232 | 0 | result.mServo = Servo_AnimationValue_Transform(aList).Consume(); |
233 | 0 | return result; |
234 | 0 | } |
235 | | |
236 | | /* static */ already_AddRefed<nsCSSValue::Array> |
237 | | AnimationValue::AppendTransformFunction(nsCSSKeyword aTransformFunction, |
238 | | nsCSSValueList**& aListTail) |
239 | 0 | { |
240 | 0 | RefPtr<nsCSSValue::Array> arr = AppendFunction(aTransformFunction); |
241 | 0 | nsCSSValueList *item = new nsCSSValueList; |
242 | 0 | item->mValue.SetArrayValue(arr, eCSSUnit_Function); |
243 | 0 |
|
244 | 0 | *aListTail = item; |
245 | 0 | aListTail = &item->mNext; |
246 | 0 |
|
247 | 0 | return arr.forget(); |
248 | 0 | } |