Bug 1684463 - [devtools] Part 1: Shorten the _createAttribute function by refactoring...
[gecko.git] / layout / style / StyleAnimationValue.cpp
blobc5983a068123f11213735e7e9fcc29a8cbebd172
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"
16 #include "mozilla/Tuple.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" // RawServoDeclarationBlock
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;
40 using nsStyleTransformMatrix::Decompose2DMatrix;
41 using nsStyleTransformMatrix::Decompose3DMatrix;
42 using nsStyleTransformMatrix::ShearType;
44 bool AnimationValue::operator==(const AnimationValue& aOther) const {
45 if (mServo && aOther.mServo) {
46 return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo);
48 if (!mServo && !aOther.mServo) {
49 return true;
51 return false;
54 bool AnimationValue::operator!=(const AnimationValue& aOther) const {
55 return !operator==(aOther);
58 float AnimationValue::GetOpacity() const {
59 MOZ_ASSERT(mServo);
60 return Servo_AnimationValue_GetOpacity(mServo);
63 nscolor AnimationValue::GetColor(nscolor aForegroundColor) const {
64 MOZ_ASSERT(mServo);
65 return Servo_AnimationValue_GetColor(mServo, aForegroundColor);
68 bool AnimationValue::IsCurrentColor() const {
69 MOZ_ASSERT(mServo);
70 return Servo_AnimationValue_IsCurrentColor(mServo);
73 const StyleTranslate& AnimationValue::GetTranslateProperty() const {
74 MOZ_ASSERT(mServo);
75 return *Servo_AnimationValue_GetTranslate(mServo);
78 const StyleRotate& AnimationValue::GetRotateProperty() const {
79 MOZ_ASSERT(mServo);
80 return *Servo_AnimationValue_GetRotate(mServo);
83 const StyleScale& AnimationValue::GetScaleProperty() const {
84 MOZ_ASSERT(mServo);
85 return *Servo_AnimationValue_GetScale(mServo);
88 const StyleTransform& AnimationValue::GetTransformProperty() const {
89 MOZ_ASSERT(mServo);
90 return *Servo_AnimationValue_GetTransform(mServo);
93 const mozilla::StyleOffsetPath& AnimationValue::GetOffsetPathProperty() const {
94 MOZ_ASSERT(mServo);
95 return *Servo_AnimationValue_GetOffsetPath(mServo);
98 const mozilla::LengthPercentage& AnimationValue::GetOffsetDistanceProperty()
99 const {
100 MOZ_ASSERT(mServo);
101 return *Servo_AnimationValue_GetOffsetDistance(mServo);
104 const mozilla::StyleOffsetRotate& AnimationValue::GetOffsetRotateProperty()
105 const {
106 MOZ_ASSERT(mServo);
107 return *Servo_AnimationValue_GetOffsetRotate(mServo);
110 const mozilla::StylePositionOrAuto& AnimationValue::GetOffsetAnchorProperty()
111 const {
112 MOZ_ASSERT(mServo);
113 return *Servo_AnimationValue_GetOffsetAnchor(mServo);
116 Size AnimationValue::GetScaleValue(const nsIFrame* aFrame) const {
117 using namespace nsStyleTransformMatrix;
119 switch (Servo_AnimationValue_GetPropertyId(mServo)) {
120 case eCSSProperty_scale: {
121 const StyleScale& scale = GetScaleProperty();
122 return scale.IsNone() ? Size(1.0, 1.0)
123 : Size(scale.AsScale()._0, scale.AsScale()._1);
125 case eCSSProperty_rotate:
126 case eCSSProperty_translate:
127 return Size(1.0, 1.0);
128 case eCSSProperty_transform:
129 break;
130 default:
131 MOZ_ASSERT_UNREACHABLE(
132 "Should only need to check in transform properties");
133 return Size(1.0, 1.0);
136 TransformReferenceBox refBox(aFrame);
137 Matrix4x4 t =
138 ReadTransforms(StyleTranslate::None(), StyleRotate::None(),
139 StyleScale::None(), Nothing(), GetTransformProperty(),
140 refBox, aFrame->PresContext()->AppUnitsPerDevPixel());
141 Matrix transform2d;
142 bool canDraw2D = t.CanDraw2D(&transform2d);
143 if (!canDraw2D) {
144 return Size();
146 return transform2d.ScaleFactors();
149 void AnimationValue::SerializeSpecifiedValue(nsCSSPropertyID aProperty,
150 const RawServoStyleSet* aRawSet,
151 nsACString& aString) const {
152 MOZ_ASSERT(mServo);
153 Servo_AnimationValue_Serialize(mServo, aProperty, aRawSet, &aString);
156 bool AnimationValue::IsInterpolableWith(nsCSSPropertyID aProperty,
157 const AnimationValue& aToValue) const {
158 if (IsNull() || aToValue.IsNull()) {
159 return false;
162 MOZ_ASSERT(mServo);
163 MOZ_ASSERT(aToValue.mServo);
164 return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo);
167 double AnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
168 const AnimationValue& aOther) const {
169 if (IsNull() || aOther.IsNull()) {
170 return 0.0;
173 MOZ_ASSERT(mServo);
174 MOZ_ASSERT(aOther.mServo);
176 double distance =
177 Servo_AnimationValues_ComputeDistance(mServo, aOther.mServo);
178 return distance < 0.0 ? 0.0 : distance;
181 /* static */
182 AnimationValue AnimationValue::FromString(nsCSSPropertyID aProperty,
183 const nsACString& aValue,
184 Element* aElement) {
185 MOZ_ASSERT(aElement);
187 AnimationValue result;
189 nsCOMPtr<Document> doc = aElement->GetComposedDoc();
190 if (!doc) {
191 return result;
194 RefPtr<PresShell> presShell = doc->GetPresShell();
195 if (!presShell) {
196 return result;
199 // GetComputedStyle() flushes style, so we shouldn't assume that any
200 // non-owning references we have are still valid.
201 RefPtr<ComputedStyle> computedStyle =
202 nsComputedDOMStyle::GetComputedStyle(aElement, nullptr);
203 MOZ_ASSERT(computedStyle);
205 RefPtr<RawServoDeclarationBlock> declarations = ServoCSSParser::ParseProperty(
206 aProperty, aValue, ServoCSSParser::GetParsingEnvironment(doc));
208 if (!declarations) {
209 return result;
212 result.mServo = presShell->StyleSet()->ComputeAnimationValue(
213 aElement, declarations, computedStyle);
214 return result;
217 /* static */
218 already_AddRefed<RawServoAnimationValue> AnimationValue::FromAnimatable(
219 nsCSSPropertyID aProperty, const layers::Animatable& aAnimatable) {
220 switch (aAnimatable.type()) {
221 case layers::Animatable::Tnull_t:
222 break;
223 case layers::Animatable::TStyleTransform: {
224 const StyleTransform& transform = aAnimatable.get_StyleTransform();
225 MOZ_ASSERT(!transform.HasPercent(),
226 "Received transform operations should have been resolved.");
227 return Servo_AnimationValue_Transform(&transform).Consume();
229 case layers::Animatable::Tfloat:
230 return Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
231 case layers::Animatable::Tnscolor:
232 return Servo_AnimationValue_Color(aProperty, aAnimatable.get_nscolor())
233 .Consume();
234 case layers::Animatable::TStyleRotate:
235 return Servo_AnimationValue_Rotate(&aAnimatable.get_StyleRotate())
236 .Consume();
237 case layers::Animatable::TStyleScale:
238 return Servo_AnimationValue_Scale(&aAnimatable.get_StyleScale())
239 .Consume();
240 case layers::Animatable::TStyleTranslate:
241 MOZ_ASSERT(
242 aAnimatable.get_StyleTranslate().IsNone() ||
243 (!aAnimatable.get_StyleTranslate()
244 .AsTranslate()
245 ._0.HasPercent() &&
246 !aAnimatable.get_StyleTranslate().AsTranslate()._1.HasPercent()),
247 "Should have been resolved already");
248 return Servo_AnimationValue_Translate(&aAnimatable.get_StyleTranslate())
249 .Consume();
250 case layers::Animatable::TStyleOffsetPath:
251 return Servo_AnimationValue_OffsetPath(&aAnimatable.get_StyleOffsetPath())
252 .Consume();
253 case layers::Animatable::TLengthPercentage:
254 return Servo_AnimationValue_OffsetDistance(
255 &aAnimatable.get_LengthPercentage())
256 .Consume();
257 case layers::Animatable::TStyleOffsetRotate:
258 return Servo_AnimationValue_OffsetRotate(
259 &aAnimatable.get_StyleOffsetRotate())
260 .Consume();
261 case layers::Animatable::TStylePositionOrAuto:
262 return Servo_AnimationValue_OffsetAnchor(
263 &aAnimatable.get_StylePositionOrAuto())
264 .Consume();
265 default:
266 MOZ_ASSERT_UNREACHABLE("Unsupported type");
268 return nullptr;