2016-01-11 02:28:35 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2009-09-10 23:03:36 +04:00
|
|
|
|
|
|
|
/* Utilities for animation of computed style values */
|
|
|
|
|
2017-02-14 22:23:11 +03:00
|
|
|
#include "mozilla/StyleAnimationValue.h"
|
|
|
|
|
2013-12-09 06:52:54 +04:00
|
|
|
#include "mozilla/ArrayUtils.h"
|
2012-08-27 05:58:23 +04:00
|
|
|
#include "mozilla/MathAlgorithms.h"
|
2019-03-29 18:12:47 +03:00
|
|
|
#include "mozilla/PresShell.h"
|
2019-04-30 04:52:53 +03:00
|
|
|
#include "mozilla/PresShellInlines.h"
|
2018-03-29 14:15:46 +03:00
|
|
|
#include "mozilla/ServoStyleSet.h"
|
2016-09-13 05:48:45 +03:00
|
|
|
#include "mozilla/Tuple.h"
|
2016-02-17 03:19:26 +03:00
|
|
|
#include "mozilla/UniquePtr.h"
|
2009-09-10 23:03:36 +04:00
|
|
|
#include "nsCOMArray.h"
|
|
|
|
#include "nsString.h"
|
2018-03-22 21:20:41 +03:00
|
|
|
#include "mozilla/ComputedStyle.h"
|
2009-09-10 23:03:36 +04:00
|
|
|
#include "nsComputedDOMStyle.h"
|
2016-02-17 23:37:00 +03:00
|
|
|
#include "nsCSSPseudoElements.h"
|
2011-03-28 20:51:59 +04:00
|
|
|
#include "mozilla/dom/Element.h"
|
2012-10-22 17:53:31 +04:00
|
|
|
#include "mozilla/FloatingPoint.h"
|
2012-10-26 17:32:10 +04:00
|
|
|
#include "mozilla/Likely.h"
|
2016-10-18 07:29:03 +03:00
|
|
|
#include "mozilla/ServoBindings.h" // RawServoDeclarationBlock
|
2017-12-01 12:35:47 +03:00
|
|
|
#include "mozilla/ServoCSSParser.h"
|
2011-07-23 02:28:07 +04:00
|
|
|
#include "gfxMatrix.h"
|
2011-09-27 01:53:33 +04:00
|
|
|
#include "gfxQuaternion.h"
|
2019-01-02 16:05:23 +03:00
|
|
|
#include "mozilla/dom/Document.h"
|
2015-07-20 05:30:40 +03:00
|
|
|
#include "nsIFrame.h"
|
2014-08-29 22:47:30 +04:00
|
|
|
#include "gfx2DGlue.h"
|
2018-03-22 21:20:41 +03:00
|
|
|
#include "mozilla/ComputedStyleInlines.h"
|
2019-03-18 21:04:44 +03:00
|
|
|
#include "mozilla/layers/LayersMessages.h"
|
2009-09-10 23:03:36 +04:00
|
|
|
|
2011-10-11 09:50:08 +04:00
|
|
|
using namespace mozilla;
|
2016-09-16 08:36:39 +03:00
|
|
|
using namespace mozilla::css;
|
2019-03-09 00:48:39 +03:00
|
|
|
using namespace mozilla::dom;
|
2014-08-29 22:47:30 +04:00
|
|
|
using namespace mozilla::gfx;
|
2016-10-04 10:00:31 +03:00
|
|
|
using nsStyleTransformMatrix::Decompose2DMatrix;
|
|
|
|
using nsStyleTransformMatrix::Decompose3DMatrix;
|
2016-10-12 07:36:58 +03:00
|
|
|
using nsStyleTransformMatrix::ShearType;
|
2010-06-29 02:49:35 +04:00
|
|
|
|
2017-03-31 12:46:37 +03:00
|
|
|
bool AnimationValue::operator==(const AnimationValue& aOther) const {
|
2017-03-31 06:04:08 +03:00
|
|
|
if (mServo && aOther.mServo) {
|
2017-03-31 12:46:37 +03:00
|
|
|
return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo);
|
|
|
|
}
|
2018-02-01 07:04:04 +03:00
|
|
|
if (!mServo && !aOther.mServo) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2017-03-31 12:46:37 +03:00
|
|
|
}
|
|
|
|
|
2017-03-09 07:33:15 +03:00
|
|
|
bool AnimationValue::operator!=(const AnimationValue& aOther) const {
|
|
|
|
return !operator==(aOther);
|
|
|
|
}
|
|
|
|
|
2017-03-31 12:46:37 +03:00
|
|
|
float AnimationValue::GetOpacity() const {
|
2018-02-01 07:04:04 +03:00
|
|
|
MOZ_ASSERT(mServo);
|
2018-05-03 19:41:17 +03:00
|
|
|
return Servo_AnimationValue_GetOpacity(mServo);
|
2017-03-31 12:46:37 +03:00
|
|
|
}
|
|
|
|
|
2018-11-28 03:58:46 +03:00
|
|
|
nscolor AnimationValue::GetColor(nscolor aForegroundColor) const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return Servo_AnimationValue_GetColor(mServo, aForegroundColor);
|
|
|
|
}
|
|
|
|
|
2020-03-04 00:48:01 +03:00
|
|
|
bool AnimationValue::IsCurrentColor() const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return Servo_AnimationValue_IsCurrentColor(mServo);
|
|
|
|
}
|
|
|
|
|
2019-05-17 02:25:10 +03:00
|
|
|
const StyleTranslate& AnimationValue::GetTranslateProperty() const {
|
2018-02-01 07:04:04 +03:00
|
|
|
MOZ_ASSERT(mServo);
|
2019-05-17 02:25:10 +03:00
|
|
|
return *Servo_AnimationValue_GetTranslate(mServo);
|
|
|
|
}
|
|
|
|
|
|
|
|
const StyleRotate& AnimationValue::GetRotateProperty() const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return *Servo_AnimationValue_GetRotate(mServo);
|
|
|
|
}
|
|
|
|
|
|
|
|
const StyleScale& AnimationValue::GetScaleProperty() const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return *Servo_AnimationValue_GetScale(mServo);
|
|
|
|
}
|
|
|
|
|
|
|
|
const StyleTransform& AnimationValue::GetTransformProperty() const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return *Servo_AnimationValue_GetTransform(mServo);
|
2017-09-25 09:25:43 +03:00
|
|
|
}
|
|
|
|
|
2019-10-31 23:07:41 +03:00
|
|
|
const mozilla::StyleOffsetPath& AnimationValue::GetOffsetPathProperty() const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return *Servo_AnimationValue_GetOffsetPath(mServo);
|
|
|
|
}
|
|
|
|
|
|
|
|
const mozilla::LengthPercentage& AnimationValue::GetOffsetDistanceProperty()
|
|
|
|
const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return *Servo_AnimationValue_GetOffsetDistance(mServo);
|
|
|
|
}
|
|
|
|
|
|
|
|
const mozilla::StyleOffsetRotate& AnimationValue::GetOffsetRotateProperty()
|
|
|
|
const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return *Servo_AnimationValue_GetOffsetRotate(mServo);
|
|
|
|
}
|
|
|
|
|
|
|
|
const mozilla::StylePositionOrAuto& AnimationValue::GetOffsetAnchorProperty()
|
|
|
|
const {
|
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
return *Servo_AnimationValue_GetOffsetAnchor(mServo);
|
|
|
|
}
|
|
|
|
|
2017-03-31 12:46:37 +03:00
|
|
|
Size AnimationValue::GetScaleValue(const nsIFrame* aFrame) const {
|
2019-05-17 02:25:10 +03:00
|
|
|
using namespace nsStyleTransformMatrix;
|
|
|
|
|
|
|
|
switch (Servo_AnimationValue_GetPropertyId(mServo)) {
|
2020-02-13 22:10:52 +03:00
|
|
|
case eCSSProperty_scale: {
|
|
|
|
const StyleScale& scale = GetScaleProperty();
|
|
|
|
return scale.IsNone() ? Size(1.0, 1.0)
|
|
|
|
: Size(scale.AsScale()._0, scale.AsScale()._1);
|
|
|
|
}
|
2019-05-17 02:25:10 +03:00
|
|
|
case eCSSProperty_rotate:
|
2020-02-13 22:10:52 +03:00
|
|
|
case eCSSProperty_translate:
|
|
|
|
return Size(1.0, 1.0);
|
2019-05-17 02:25:10 +03:00
|
|
|
case eCSSProperty_transform:
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE(
|
|
|
|
"Should only need to check in transform properties");
|
|
|
|
return Size(1.0, 1.0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TransformReferenceBox refBox(aFrame);
|
|
|
|
Matrix4x4 t =
|
2020-02-13 22:10:52 +03:00
|
|
|
ReadTransforms(StyleTranslate::None(), StyleRotate::None(),
|
|
|
|
StyleScale::None(), Nothing(), GetTransformProperty(),
|
|
|
|
refBox, aFrame->PresContext()->AppUnitsPerDevPixel());
|
2019-05-17 02:25:10 +03:00
|
|
|
Matrix transform2d;
|
|
|
|
bool canDraw2D = t.CanDraw2D(&transform2d);
|
|
|
|
if (!canDraw2D) {
|
|
|
|
return Size();
|
|
|
|
}
|
2020-11-18 21:53:01 +03:00
|
|
|
return transform2d.ScaleFactors();
|
2017-03-31 12:46:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void AnimationValue::SerializeSpecifiedValue(nsCSSPropertyID aProperty,
|
2020-01-08 14:55:28 +03:00
|
|
|
const RawServoStyleSet* aRawSet,
|
2020-12-17 17:04:35 +03:00
|
|
|
nsACString& aString) const {
|
2018-02-01 07:04:04 +03:00
|
|
|
MOZ_ASSERT(mServo);
|
2020-01-08 14:55:28 +03:00
|
|
|
Servo_AnimationValue_Serialize(mServo, aProperty, aRawSet, &aString);
|
2017-03-31 12:46:37 +03:00
|
|
|
}
|
2017-04-12 11:26:59 +03:00
|
|
|
|
|
|
|
bool AnimationValue::IsInterpolableWith(nsCSSPropertyID aProperty,
|
|
|
|
const AnimationValue& aToValue) const {
|
|
|
|
if (IsNull() || aToValue.IsNull()) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-02-01 07:04:04 +03:00
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
MOZ_ASSERT(aToValue.mServo);
|
2018-05-03 19:41:17 +03:00
|
|
|
return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo);
|
2017-04-12 11:26:59 +03:00
|
|
|
}
|
2017-04-26 15:05:04 +03:00
|
|
|
|
|
|
|
double AnimationValue::ComputeDistance(nsCSSPropertyID aProperty,
|
2020-03-09 21:44:22 +03:00
|
|
|
const AnimationValue& aOther) const {
|
2017-04-26 15:05:04 +03:00
|
|
|
if (IsNull() || aOther.IsNull()) {
|
|
|
|
return 0.0;
|
|
|
|
}
|
|
|
|
|
2018-02-01 07:04:04 +03:00
|
|
|
MOZ_ASSERT(mServo);
|
|
|
|
MOZ_ASSERT(aOther.mServo);
|
2017-04-26 15:05:04 +03:00
|
|
|
|
2018-05-03 19:41:17 +03:00
|
|
|
double distance =
|
|
|
|
Servo_AnimationValues_ComputeDistance(mServo, aOther.mServo);
|
|
|
|
return distance < 0.0 ? 0.0 : distance;
|
2017-04-26 15:05:04 +03:00
|
|
|
}
|
2017-05-03 06:15:27 +03:00
|
|
|
|
2019-02-26 01:09:24 +03:00
|
|
|
/* static */
|
|
|
|
AnimationValue AnimationValue::FromString(nsCSSPropertyID aProperty,
|
2020-12-17 17:04:35 +03:00
|
|
|
const nsACString& aValue,
|
2019-02-26 01:09:24 +03:00
|
|
|
Element* aElement) {
|
2017-05-03 06:15:27 +03:00
|
|
|
MOZ_ASSERT(aElement);
|
|
|
|
|
|
|
|
AnimationValue result;
|
|
|
|
|
2019-01-02 16:05:23 +03:00
|
|
|
nsCOMPtr<Document> doc = aElement->GetComposedDoc();
|
2017-05-03 06:15:27 +03:00
|
|
|
if (!doc) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-03-29 18:12:47 +03:00
|
|
|
RefPtr<PresShell> presShell = doc->GetPresShell();
|
|
|
|
if (!presShell) {
|
2017-05-03 06:15:27 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
// GetComputedStyle() flushes style, so we shouldn't assume that any
|
2017-05-03 06:15:27 +03:00
|
|
|
// non-owning references we have are still valid.
|
2018-03-22 16:49:21 +03:00
|
|
|
RefPtr<ComputedStyle> computedStyle =
|
2018-03-22 21:20:41 +03:00
|
|
|
nsComputedDOMStyle::GetComputedStyle(aElement, nullptr);
|
2018-03-22 16:49:21 +03:00
|
|
|
MOZ_ASSERT(computedStyle);
|
2017-05-03 06:15:27 +03:00
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
RefPtr<RawServoDeclarationBlock> declarations = ServoCSSParser::ParseProperty(
|
|
|
|
aProperty, aValue, ServoCSSParser::GetParsingEnvironment(doc));
|
2017-05-03 06:15:27 +03:00
|
|
|
|
2018-03-22 21:20:41 +03:00
|
|
|
if (!declarations) {
|
2017-05-03 06:15:27 +03:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2019-03-29 18:12:47 +03:00
|
|
|
result.mServo = presShell->StyleSet()->ComputeAnimationValue(
|
2018-03-29 14:15:46 +03:00
|
|
|
aElement, declarations, computedStyle);
|
2018-03-22 21:20:41 +03:00
|
|
|
return result;
|
2017-05-03 06:15:27 +03:00
|
|
|
}
|
2017-10-27 22:04:52 +03:00
|
|
|
|
2019-02-26 01:09:24 +03:00
|
|
|
/* static */
|
2019-03-18 21:04:50 +03:00
|
|
|
already_AddRefed<RawServoAnimationValue> AnimationValue::FromAnimatable(
|
|
|
|
nsCSSPropertyID aProperty, const layers::Animatable& aAnimatable) {
|
2019-03-18 21:04:44 +03:00
|
|
|
switch (aAnimatable.type()) {
|
|
|
|
case layers::Animatable::Tnull_t:
|
|
|
|
break;
|
2020-01-22 23:20:38 +03:00
|
|
|
case layers::Animatable::TStyleTransform: {
|
|
|
|
const StyleTransform& transform = aAnimatable.get_StyleTransform();
|
|
|
|
MOZ_ASSERT(!transform.HasPercent(),
|
|
|
|
"Received transform operations should have been resolved.");
|
|
|
|
return Servo_AnimationValue_Transform(&transform).Consume();
|
2019-03-18 21:04:44 +03:00
|
|
|
}
|
|
|
|
case layers::Animatable::Tfloat:
|
2019-05-17 02:25:10 +03:00
|
|
|
return Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
|
2019-03-18 21:04:44 +03:00
|
|
|
case layers::Animatable::Tnscolor:
|
2019-05-17 02:25:10 +03:00
|
|
|
return Servo_AnimationValue_Color(aProperty, aAnimatable.get_nscolor())
|
|
|
|
.Consume();
|
2020-01-22 23:18:31 +03:00
|
|
|
case layers::Animatable::TStyleRotate:
|
|
|
|
return Servo_AnimationValue_Rotate(&aAnimatable.get_StyleRotate())
|
|
|
|
.Consume();
|
|
|
|
case layers::Animatable::TStyleScale:
|
|
|
|
return Servo_AnimationValue_Scale(&aAnimatable.get_StyleScale())
|
|
|
|
.Consume();
|
|
|
|
case layers::Animatable::TStyleTranslate:
|
|
|
|
MOZ_ASSERT(
|
|
|
|
aAnimatable.get_StyleTranslate().IsNone() ||
|
|
|
|
(!aAnimatable.get_StyleTranslate()
|
|
|
|
.AsTranslate()
|
|
|
|
._0.HasPercent() &&
|
|
|
|
!aAnimatable.get_StyleTranslate().AsTranslate()._1.HasPercent()),
|
|
|
|
"Should have been resolved already");
|
|
|
|
return Servo_AnimationValue_Translate(&aAnimatable.get_StyleTranslate())
|
|
|
|
.Consume();
|
2020-01-22 23:18:35 +03:00
|
|
|
case layers::Animatable::TStyleOffsetPath:
|
|
|
|
return Servo_AnimationValue_OffsetPath(&aAnimatable.get_StyleOffsetPath())
|
|
|
|
.Consume();
|
2019-10-31 23:07:41 +03:00
|
|
|
case layers::Animatable::TLengthPercentage:
|
|
|
|
return Servo_AnimationValue_OffsetDistance(
|
|
|
|
&aAnimatable.get_LengthPercentage())
|
|
|
|
.Consume();
|
2020-01-22 23:18:38 +03:00
|
|
|
case layers::Animatable::TStyleOffsetRotate:
|
|
|
|
return Servo_AnimationValue_OffsetRotate(
|
|
|
|
&aAnimatable.get_StyleOffsetRotate())
|
|
|
|
.Consume();
|
|
|
|
case layers::Animatable::TStylePositionOrAuto:
|
|
|
|
return Servo_AnimationValue_OffsetAnchor(
|
|
|
|
&aAnimatable.get_StylePositionOrAuto())
|
|
|
|
.Consume();
|
2019-03-18 21:04:44 +03:00
|
|
|
default:
|
|
|
|
MOZ_ASSERT_UNREACHABLE("Unsupported type");
|
|
|
|
}
|
2019-05-17 02:25:10 +03:00
|
|
|
return nullptr;
|
2017-10-17 08:11:19 +03:00
|
|
|
}
|