Coverage Report

Created: 2018-09-25 14:53

/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
}