Backed out changeset 1b14354719c0 (bug 1895254) for causing bustages on NavigationTra...
[gecko.git] / layout / style / StyleAnimationValue.cpp
blobb87fb5f21bf0945313f80069007d216f911ff98f
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/. */
7 /* Utilities for animation of computed style values */
9 #include "mozilla/StyleAnimationValue.h"
11 #include "mozilla/ArrayUtils.h"
12 #include "mozilla/MathAlgorithms.h"
13 #include "mozilla/PresShell.h"
14 #include "mozilla/PresShellInlines.h"
15 #include "mozilla/ServoStyleSet.h"
17 #include "mozilla/UniquePtr.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" // StyleLockedDeclarationBlock
27 #include "mozilla/ServoCSSParser.h"
28 #include "gfxMatrix.h"
29 #include "gfxQuaternion.h"
30 #include "mozilla/dom/Document.h"
31 #include "nsIFrame.h"
32 #include "gfx2DGlue.h"
33 #include "mozilla/ComputedStyleInlines.h"
34 #include "mozilla/layers/LayersMessages.h"
36 using namespace mozilla;
37 using namespace mozilla::css;
38 using namespace mozilla::dom;
39 using namespace mozilla::gfx;
41 bool AnimationValue::operator==(const AnimationValue& aOther) const {
42 if (mServo && aOther.mServo) {
43 return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo);
45 if (!mServo && !aOther.mServo) {
46 return true;
48 return false;
51 bool AnimationValue::operator!=(const AnimationValue& aOther) const {
52 return !operator==(aOther);
55 float AnimationValue::GetOpacity() const {
56 MOZ_ASSERT(mServo);
57 return Servo_AnimationValue_GetOpacity(mServo);
60 nscolor AnimationValue::GetColor(nscolor aForegroundColor) const {
61 MOZ_ASSERT(mServo);
62 return Servo_AnimationValue_GetColor(mServo, aForegroundColor);
65 bool AnimationValue::IsCurrentColor() const {
66 MOZ_ASSERT(mServo);
67 return Servo_AnimationValue_IsCurrentColor(mServo);
70 const StyleTranslate& AnimationValue::GetTranslateProperty() const {
71 MOZ_ASSERT(mServo);
72 return *Servo_AnimationValue_GetTranslate(mServo);
75 const StyleRotate& AnimationValue::GetRotateProperty() const {
76 MOZ_ASSERT(mServo);
77 return *Servo_AnimationValue_GetRotate(mServo);
80 const StyleScale& AnimationValue::GetScaleProperty() const {
81 MOZ_ASSERT(mServo);
82 return *Servo_AnimationValue_GetScale(mServo);
85 const StyleTransform& AnimationValue::GetTransformProperty() const {
86 MOZ_ASSERT(mServo);
87 return *Servo_AnimationValue_GetTransform(mServo);
90 void AnimationValue::GetOffsetPathProperty(StyleOffsetPath& aOffsetPath) const {
91 MOZ_ASSERT(mServo);
92 Servo_AnimationValue_GetOffsetPath(mServo, &aOffsetPath);
95 const mozilla::LengthPercentage& AnimationValue::GetOffsetDistanceProperty()
96 const {
97 MOZ_ASSERT(mServo);
98 return *Servo_AnimationValue_GetOffsetDistance(mServo);
101 const mozilla::StyleOffsetRotate& AnimationValue::GetOffsetRotateProperty()
102 const {
103 MOZ_ASSERT(mServo);
104 return *Servo_AnimationValue_GetOffsetRotate(mServo);
107 const mozilla::StylePositionOrAuto& AnimationValue::GetOffsetAnchorProperty()
108 const {
109 MOZ_ASSERT(mServo);
110 return *Servo_AnimationValue_GetOffsetAnchor(mServo);
113 const mozilla::StyleOffsetPosition& AnimationValue::GetOffsetPositionProperty()
114 const {
115 MOZ_ASSERT(mServo);
116 return *Servo_AnimationValue_GetOffsetPosition(mServo);
119 bool AnimationValue::IsOffsetPathUrl() const {
120 return mServo && Servo_AnimationValue_IsOffsetPathUrl(mServo);
123 MatrixScales AnimationValue::GetScaleValue(const nsIFrame* aFrame) const {
124 using namespace nsStyleTransformMatrix;
126 AnimatedPropertyID property(eCSSProperty_UNKNOWN);
127 Servo_AnimationValue_GetPropertyId(mServo, &property);
128 switch (property.mID) {
129 case eCSSProperty_scale: {
130 const StyleScale& scale = GetScaleProperty();
131 return scale.IsNone()
132 ? MatrixScales()
133 : MatrixScales(scale.AsScale()._0, scale.AsScale()._1);
135 case eCSSProperty_rotate:
136 case eCSSProperty_translate:
137 return MatrixScales();
138 case eCSSProperty_transform:
139 break;
140 default:
141 MOZ_ASSERT_UNREACHABLE(
142 "Should only need to check in transform properties");
143 return MatrixScales();
146 TransformReferenceBox refBox(aFrame);
147 Matrix4x4 t =
148 ReadTransforms(StyleTranslate::None(), StyleRotate::None(),
149 StyleScale::None(), nullptr, GetTransformProperty(),
150 refBox, aFrame->PresContext()->AppUnitsPerDevPixel());
151 Matrix transform2d;
152 bool canDraw2D = t.CanDraw2D(&transform2d);
153 if (!canDraw2D) {
154 return MatrixScales(0, 0);
156 return transform2d.ScaleFactors();
159 void AnimationValue::SerializeSpecifiedValue(
160 const AnimatedPropertyID& aProperty,
161 const StylePerDocumentStyleData* aRawData, nsACString& aString) const {
162 MOZ_ASSERT(mServo);
163 Servo_AnimationValue_Serialize(mServo, &aProperty, aRawData, &aString);
166 bool AnimationValue::IsInterpolableWith(const AnimatedPropertyID& aProperty,
167 const AnimationValue& aToValue) const {
168 if (IsNull() || aToValue.IsNull()) {
169 return false;
172 MOZ_ASSERT(mServo);
173 MOZ_ASSERT(aToValue.mServo);
174 return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo);
177 double AnimationValue::ComputeDistance(const AnimationValue& aOther) const {
178 if (IsNull() || aOther.IsNull()) {
179 return 0.0;
182 MOZ_ASSERT(mServo);
183 MOZ_ASSERT(aOther.mServo);
185 double distance =
186 Servo_AnimationValues_ComputeDistance(mServo, aOther.mServo);
187 return distance < 0.0 ? 0.0 : distance;
190 /* static */
191 AnimationValue AnimationValue::FromString(AnimatedPropertyID& aProperty,
192 const nsACString& aValue,
193 Element* aElement) {
194 MOZ_ASSERT(aElement);
196 AnimationValue result;
198 nsCOMPtr<Document> doc = aElement->GetComposedDoc();
199 if (!doc) {
200 return result;
203 RefPtr<PresShell> presShell = doc->GetPresShell();
204 if (!presShell) {
205 return result;
208 // GetComputedStyle() flushes style, so we shouldn't assume that any
209 // non-owning references we have are still valid.
210 RefPtr<const ComputedStyle> computedStyle =
211 nsComputedDOMStyle::GetComputedStyle(aElement);
212 MOZ_ASSERT(computedStyle);
214 RefPtr<StyleLockedDeclarationBlock> declarations =
215 ServoCSSParser::ParseProperty(aProperty, aValue,
216 ServoCSSParser::GetParsingEnvironment(doc),
217 StyleParsingMode::DEFAULT);
219 if (!declarations) {
220 return result;
223 result.mServo = presShell->StyleSet()->ComputeAnimationValue(
224 aElement, declarations, computedStyle);
225 return result;
228 /* static */
229 already_AddRefed<StyleAnimationValue> AnimationValue::FromAnimatable(
230 nsCSSPropertyID aProperty, const layers::Animatable& aAnimatable) {
231 switch (aAnimatable.type()) {
232 case layers::Animatable::Tnull_t:
233 break;
234 case layers::Animatable::TStyleTransform: {
235 const StyleTransform& transform = aAnimatable.get_StyleTransform();
236 MOZ_ASSERT(!transform.HasPercent(),
237 "Received transform operations should have been resolved.");
238 return Servo_AnimationValue_Transform(&transform).Consume();
240 case layers::Animatable::Tfloat:
241 return Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
242 case layers::Animatable::Tnscolor:
243 return Servo_AnimationValue_Color(aProperty, aAnimatable.get_nscolor())
244 .Consume();
245 case layers::Animatable::TStyleRotate:
246 return Servo_AnimationValue_Rotate(&aAnimatable.get_StyleRotate())
247 .Consume();
248 case layers::Animatable::TStyleScale:
249 return Servo_AnimationValue_Scale(&aAnimatable.get_StyleScale())
250 .Consume();
251 case layers::Animatable::TStyleTranslate:
252 MOZ_ASSERT(
253 aAnimatable.get_StyleTranslate().IsNone() ||
254 (!aAnimatable.get_StyleTranslate()
255 .AsTranslate()
256 ._0.HasPercent() &&
257 !aAnimatable.get_StyleTranslate().AsTranslate()._1.HasPercent()),
258 "Should have been resolved already");
259 return Servo_AnimationValue_Translate(&aAnimatable.get_StyleTranslate())
260 .Consume();
261 case layers::Animatable::TStyleOffsetPath:
262 return Servo_AnimationValue_OffsetPath(&aAnimatable.get_StyleOffsetPath())
263 .Consume();
264 case layers::Animatable::TLengthPercentage:
265 return Servo_AnimationValue_OffsetDistance(
266 &aAnimatable.get_LengthPercentage())
267 .Consume();
268 case layers::Animatable::TStyleOffsetRotate:
269 return Servo_AnimationValue_OffsetRotate(
270 &aAnimatable.get_StyleOffsetRotate())
271 .Consume();
272 case layers::Animatable::TStylePositionOrAuto:
273 return Servo_AnimationValue_OffsetAnchor(
274 &aAnimatable.get_StylePositionOrAuto())
275 .Consume();
276 case layers::Animatable::TStyleOffsetPosition:
277 return Servo_AnimationValue_OffsetPosition(
278 &aAnimatable.get_StyleOffsetPosition())
279 .Consume();
280 default:
281 MOZ_ASSERT_UNREACHABLE("Unsupported type");
283 return nullptr;