diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /layout/style/StyleAnimationValue.cpp | |
parent | Initial commit. (diff) | |
download | firefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'layout/style/StyleAnimationValue.cpp')
-rw-r--r-- | layout/style/StyleAnimationValue.cpp | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/layout/style/StyleAnimationValue.cpp b/layout/style/StyleAnimationValue.cpp new file mode 100644 index 0000000000..9933d6b32c --- /dev/null +++ b/layout/style/StyleAnimationValue.cpp @@ -0,0 +1,267 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +/* Utilities for animation of computed style values */ + +#include "mozilla/StyleAnimationValue.h" + +#include "mozilla/ArrayUtils.h" +#include "mozilla/MathAlgorithms.h" +#include "mozilla/PresShell.h" +#include "mozilla/PresShellInlines.h" +#include "mozilla/ServoStyleSet.h" +#include "mozilla/Tuple.h" +#include "mozilla/UniquePtr.h" +#include "nsCOMArray.h" +#include "nsString.h" +#include "mozilla/ComputedStyle.h" +#include "nsComputedDOMStyle.h" +#include "nsCSSPseudoElements.h" +#include "mozilla/dom/Element.h" +#include "mozilla/FloatingPoint.h" +#include "mozilla/Likely.h" +#include "mozilla/ServoBindings.h" // RawServoDeclarationBlock +#include "mozilla/ServoCSSParser.h" +#include "gfxMatrix.h" +#include "gfxQuaternion.h" +#include "mozilla/dom/Document.h" +#include "nsIFrame.h" +#include "gfx2DGlue.h" +#include "mozilla/ComputedStyleInlines.h" +#include "mozilla/layers/LayersMessages.h" + +using namespace mozilla; +using namespace mozilla::css; +using namespace mozilla::dom; +using namespace mozilla::gfx; + +bool AnimationValue::operator==(const AnimationValue& aOther) const { + if (mServo && aOther.mServo) { + return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo); + } + if (!mServo && !aOther.mServo) { + return true; + } + return false; +} + +bool AnimationValue::operator!=(const AnimationValue& aOther) const { + return !operator==(aOther); +} + +float AnimationValue::GetOpacity() const { + MOZ_ASSERT(mServo); + return Servo_AnimationValue_GetOpacity(mServo); +} + +nscolor AnimationValue::GetColor(nscolor aForegroundColor) const { + MOZ_ASSERT(mServo); + return Servo_AnimationValue_GetColor(mServo, aForegroundColor); +} + +bool AnimationValue::IsCurrentColor() const { + MOZ_ASSERT(mServo); + return Servo_AnimationValue_IsCurrentColor(mServo); +} + +const StyleTranslate& AnimationValue::GetTranslateProperty() const { + MOZ_ASSERT(mServo); + 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); +} + +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); +} + +MatrixScales AnimationValue::GetScaleValue(const nsIFrame* aFrame) const { + using namespace nsStyleTransformMatrix; + + switch (Servo_AnimationValue_GetPropertyId(mServo)) { + case eCSSProperty_scale: { + const StyleScale& scale = GetScaleProperty(); + return scale.IsNone() + ? MatrixScales() + : MatrixScales(scale.AsScale()._0, scale.AsScale()._1); + } + case eCSSProperty_rotate: + case eCSSProperty_translate: + return MatrixScales(); + case eCSSProperty_transform: + break; + default: + MOZ_ASSERT_UNREACHABLE( + "Should only need to check in transform properties"); + return MatrixScales(); + } + + TransformReferenceBox refBox(aFrame); + Matrix4x4 t = + ReadTransforms(StyleTranslate::None(), StyleRotate::None(), + StyleScale::None(), Nothing(), GetTransformProperty(), + refBox, aFrame->PresContext()->AppUnitsPerDevPixel()); + Matrix transform2d; + bool canDraw2D = t.CanDraw2D(&transform2d); + if (!canDraw2D) { + return MatrixScales(0, 0); + } + return transform2d.ScaleFactors(); +} + +void AnimationValue::SerializeSpecifiedValue(nsCSSPropertyID aProperty, + const RawServoStyleSet* aRawSet, + nsACString& aString) const { + MOZ_ASSERT(mServo); + Servo_AnimationValue_Serialize(mServo, aProperty, aRawSet, &aString); +} + +bool AnimationValue::IsInterpolableWith(nsCSSPropertyID aProperty, + const AnimationValue& aToValue) const { + if (IsNull() || aToValue.IsNull()) { + return false; + } + + MOZ_ASSERT(mServo); + MOZ_ASSERT(aToValue.mServo); + return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo); +} + +double AnimationValue::ComputeDistance(nsCSSPropertyID aProperty, + const AnimationValue& aOther) const { + if (IsNull() || aOther.IsNull()) { + return 0.0; + } + + MOZ_ASSERT(mServo); + MOZ_ASSERT(aOther.mServo); + + double distance = + Servo_AnimationValues_ComputeDistance(mServo, aOther.mServo); + return distance < 0.0 ? 0.0 : distance; +} + +/* static */ +AnimationValue AnimationValue::FromString(nsCSSPropertyID aProperty, + const nsACString& aValue, + Element* aElement) { + MOZ_ASSERT(aElement); + + AnimationValue result; + + nsCOMPtr<Document> doc = aElement->GetComposedDoc(); + if (!doc) { + return result; + } + + RefPtr<PresShell> presShell = doc->GetPresShell(); + if (!presShell) { + return result; + } + + // GetComputedStyle() flushes style, so we shouldn't assume that any + // non-owning references we have are still valid. + RefPtr<const ComputedStyle> computedStyle = + nsComputedDOMStyle::GetComputedStyle(aElement); + MOZ_ASSERT(computedStyle); + + RefPtr<RawServoDeclarationBlock> declarations = ServoCSSParser::ParseProperty( + aProperty, aValue, ServoCSSParser::GetParsingEnvironment(doc)); + + if (!declarations) { + return result; + } + + result.mServo = presShell->StyleSet()->ComputeAnimationValue( + aElement, declarations, computedStyle); + return result; +} + +/* static */ +already_AddRefed<RawServoAnimationValue> AnimationValue::FromAnimatable( + nsCSSPropertyID aProperty, const layers::Animatable& aAnimatable) { + switch (aAnimatable.type()) { + case layers::Animatable::Tnull_t: + break; + 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(); + } + case layers::Animatable::Tfloat: + return Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume(); + case layers::Animatable::Tnscolor: + return Servo_AnimationValue_Color(aProperty, aAnimatable.get_nscolor()) + .Consume(); + 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(); + case layers::Animatable::TStyleOffsetPath: + return Servo_AnimationValue_OffsetPath(&aAnimatable.get_StyleOffsetPath()) + .Consume(); + case layers::Animatable::TLengthPercentage: + return Servo_AnimationValue_OffsetDistance( + &aAnimatable.get_LengthPercentage()) + .Consume(); + case layers::Animatable::TStyleOffsetRotate: + return Servo_AnimationValue_OffsetRotate( + &aAnimatable.get_StyleOffsetRotate()) + .Consume(); + case layers::Animatable::TStylePositionOrAuto: + return Servo_AnimationValue_OffsetAnchor( + &aAnimatable.get_StylePositionOrAuto()) + .Consume(); + default: + MOZ_ASSERT_UNREACHABLE("Unsupported type"); + } + return nullptr; +} |