tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

StyleAnimationValue.cpp (9174B)


      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 "gfx2DGlue.h"
     12 #include "gfxMatrix.h"
     13 #include "gfxQuaternion.h"
     14 #include "mozilla/ComputedStyle.h"
     15 #include "mozilla/ComputedStyleInlines.h"
     16 #include "mozilla/PresShell.h"
     17 #include "mozilla/PresShellInlines.h"
     18 #include "mozilla/ServoBindings.h"  // StyleLockedDeclarationBlock
     19 #include "mozilla/ServoCSSParser.h"
     20 #include "mozilla/ServoStyleSet.h"
     21 #include "mozilla/dom/Document.h"
     22 #include "mozilla/dom/Element.h"
     23 #include "mozilla/layers/LayersMessages.h"
     24 #include "nsCOMArray.h"
     25 #include "nsCSSPseudoElements.h"
     26 #include "nsComputedDOMStyle.h"
     27 #include "nsIFrame.h"
     28 #include "nsString.h"
     29 
     30 using namespace mozilla;
     31 using namespace mozilla::css;
     32 using namespace mozilla::dom;
     33 using namespace mozilla::gfx;
     34 
     35 bool AnimationValue::operator==(const AnimationValue& aOther) const {
     36  if (mServo && aOther.mServo) {
     37    return Servo_AnimationValue_DeepEqual(mServo, aOther.mServo);
     38  }
     39  if (!mServo && !aOther.mServo) {
     40    return true;
     41  }
     42  return false;
     43 }
     44 
     45 bool AnimationValue::operator!=(const AnimationValue& aOther) const {
     46  return !operator==(aOther);
     47 }
     48 
     49 float AnimationValue::GetOpacity() const {
     50  MOZ_ASSERT(mServo);
     51  return Servo_AnimationValue_GetOpacity(mServo);
     52 }
     53 
     54 nscolor AnimationValue::GetColor(nscolor aForegroundColor) const {
     55  MOZ_ASSERT(mServo);
     56  return Servo_AnimationValue_GetColor(mServo, aForegroundColor);
     57 }
     58 
     59 bool AnimationValue::IsCurrentColor() const {
     60  MOZ_ASSERT(mServo);
     61  return Servo_AnimationValue_IsCurrentColor(mServo);
     62 }
     63 
     64 const StyleTranslate& AnimationValue::GetTranslateProperty() const {
     65  MOZ_ASSERT(mServo);
     66  return *Servo_AnimationValue_GetTranslate(mServo);
     67 }
     68 
     69 const StyleRotate& AnimationValue::GetRotateProperty() const {
     70  MOZ_ASSERT(mServo);
     71  return *Servo_AnimationValue_GetRotate(mServo);
     72 }
     73 
     74 const StyleScale& AnimationValue::GetScaleProperty() const {
     75  MOZ_ASSERT(mServo);
     76  return *Servo_AnimationValue_GetScale(mServo);
     77 }
     78 
     79 const StyleTransform& AnimationValue::GetTransformProperty() const {
     80  MOZ_ASSERT(mServo);
     81  return *Servo_AnimationValue_GetTransform(mServo);
     82 }
     83 
     84 void AnimationValue::GetOffsetPathProperty(StyleOffsetPath& aOffsetPath) const {
     85  MOZ_ASSERT(mServo);
     86  Servo_AnimationValue_GetOffsetPath(mServo, &aOffsetPath);
     87 }
     88 
     89 const mozilla::LengthPercentage& AnimationValue::GetOffsetDistanceProperty()
     90    const {
     91  MOZ_ASSERT(mServo);
     92  return *Servo_AnimationValue_GetOffsetDistance(mServo);
     93 }
     94 
     95 const mozilla::StyleOffsetRotate& AnimationValue::GetOffsetRotateProperty()
     96    const {
     97  MOZ_ASSERT(mServo);
     98  return *Servo_AnimationValue_GetOffsetRotate(mServo);
     99 }
    100 
    101 const mozilla::StylePositionOrAuto& AnimationValue::GetOffsetAnchorProperty()
    102    const {
    103  MOZ_ASSERT(mServo);
    104  return *Servo_AnimationValue_GetOffsetAnchor(mServo);
    105 }
    106 
    107 const mozilla::StyleOffsetPosition& AnimationValue::GetOffsetPositionProperty()
    108    const {
    109  MOZ_ASSERT(mServo);
    110  return *Servo_AnimationValue_GetOffsetPosition(mServo);
    111 }
    112 
    113 bool AnimationValue::IsOffsetPathUrl() const {
    114  return mServo && Servo_AnimationValue_IsOffsetPathUrl(mServo);
    115 }
    116 
    117 MatrixScales AnimationValue::GetScaleValue(const nsIFrame* aFrame) const {
    118  using namespace nsStyleTransformMatrix;
    119 
    120  CSSPropertyId property(eCSSProperty_UNKNOWN);
    121  Servo_AnimationValue_GetPropertyId(mServo, &property);
    122  switch (property.mId) {
    123    case eCSSProperty_scale: {
    124      const StyleScale& scale = GetScaleProperty();
    125      return scale.IsNone()
    126                 ? MatrixScales()
    127                 : MatrixScales(scale.AsScale()._0, scale.AsScale()._1);
    128    }
    129    case eCSSProperty_rotate:
    130    case eCSSProperty_translate:
    131      return MatrixScales();
    132    case eCSSProperty_transform:
    133      break;
    134    default:
    135      MOZ_ASSERT_UNREACHABLE(
    136          "Should only need to check in transform properties");
    137      return MatrixScales();
    138  }
    139 
    140  TransformReferenceBox refBox(aFrame);
    141  Matrix4x4 t =
    142      ReadTransforms(StyleTranslate::None(), StyleRotate::None(),
    143                     StyleScale::None(), nullptr, GetTransformProperty(),
    144                     refBox, aFrame->PresContext()->AppUnitsPerDevPixel());
    145  Matrix transform2d;
    146  bool canDraw2D = t.CanDraw2D(&transform2d);
    147  if (!canDraw2D) {
    148    return MatrixScales(0, 0);
    149  }
    150  return transform2d.ScaleFactors();
    151 }
    152 
    153 void AnimationValue::SerializeSpecifiedValue(
    154    const CSSPropertyId& aProperty, const StylePerDocumentStyleData* aRawData,
    155    nsACString& aString) const {
    156  MOZ_ASSERT(mServo);
    157  Servo_AnimationValue_Serialize(mServo, &aProperty, aRawData, &aString);
    158 }
    159 
    160 bool AnimationValue::IsInterpolableWith(const CSSPropertyId& aProperty,
    161                                        const AnimationValue& aToValue) const {
    162  if (IsNull() || aToValue.IsNull()) {
    163    return false;
    164  }
    165 
    166  MOZ_ASSERT(mServo);
    167  MOZ_ASSERT(aToValue.mServo);
    168  return Servo_AnimationValues_IsInterpolable(mServo, aToValue.mServo);
    169 }
    170 
    171 double AnimationValue::ComputeDistance(const AnimationValue& aOther) const {
    172  if (IsNull() || aOther.IsNull()) {
    173    return 0.0;
    174  }
    175 
    176  MOZ_ASSERT(mServo);
    177  MOZ_ASSERT(aOther.mServo);
    178 
    179  double distance =
    180      Servo_AnimationValues_ComputeDistance(mServo, aOther.mServo);
    181  return distance < 0.0 ? 0.0 : distance;
    182 }
    183 
    184 /* static */
    185 AnimationValue AnimationValue::FromString(CSSPropertyId& aProperty,
    186                                          const nsACString& aValue,
    187                                          Element* aElement) {
    188  MOZ_ASSERT(aElement);
    189 
    190  AnimationValue result;
    191 
    192  nsCOMPtr<Document> doc = aElement->GetComposedDoc();
    193  if (!doc) {
    194    return result;
    195  }
    196 
    197  RefPtr<PresShell> presShell = doc->GetPresShell();
    198  if (!presShell) {
    199    return result;
    200  }
    201 
    202  // GetComputedStyle() flushes style, so we shouldn't assume that any
    203  // non-owning references we have are still valid.
    204  RefPtr<const ComputedStyle> computedStyle =
    205      nsComputedDOMStyle::GetComputedStyle(aElement);
    206  MOZ_ASSERT(computedStyle);
    207 
    208  RefPtr<StyleLockedDeclarationBlock> declarations =
    209      ServoCSSParser::ParseProperty(aProperty, aValue,
    210                                    ServoCSSParser::GetParsingEnvironment(doc),
    211                                    StyleParsingMode::DEFAULT);
    212 
    213  if (!declarations) {
    214    return result;
    215  }
    216 
    217  result.mServo = presShell->StyleSet()->ComputeAnimationValue(
    218      aElement, declarations, computedStyle);
    219  return result;
    220 }
    221 
    222 /* static */
    223 already_AddRefed<StyleAnimationValue> AnimationValue::FromAnimatable(
    224    NonCustomCSSPropertyId aProperty, const layers::Animatable& aAnimatable) {
    225  switch (aAnimatable.type()) {
    226    case layers::Animatable::Tnull_t:
    227      break;
    228    case layers::Animatable::TStyleTransform: {
    229      const StyleTransform& transform = aAnimatable.get_StyleTransform();
    230      MOZ_ASSERT(!transform.HasPercent(),
    231                 "Received transform operations should have been resolved.");
    232      return Servo_AnimationValue_Transform(&transform).Consume();
    233    }
    234    case layers::Animatable::Tfloat:
    235      return Servo_AnimationValue_Opacity(aAnimatable.get_float()).Consume();
    236    case layers::Animatable::Tnscolor:
    237      return Servo_AnimationValue_Color(aProperty, aAnimatable.get_nscolor())
    238          .Consume();
    239    case layers::Animatable::TStyleRotate:
    240      return Servo_AnimationValue_Rotate(&aAnimatable.get_StyleRotate())
    241          .Consume();
    242    case layers::Animatable::TStyleScale:
    243      return Servo_AnimationValue_Scale(&aAnimatable.get_StyleScale())
    244          .Consume();
    245    case layers::Animatable::TStyleTranslate:
    246      MOZ_ASSERT(
    247          aAnimatable.get_StyleTranslate().IsNone() ||
    248              (!aAnimatable.get_StyleTranslate()
    249                    .AsTranslate()
    250                    ._0.HasPercent() &&
    251               !aAnimatable.get_StyleTranslate().AsTranslate()._1.HasPercent()),
    252          "Should have been resolved already");
    253      return Servo_AnimationValue_Translate(&aAnimatable.get_StyleTranslate())
    254          .Consume();
    255    case layers::Animatable::TStyleOffsetPath:
    256      return Servo_AnimationValue_OffsetPath(&aAnimatable.get_StyleOffsetPath())
    257          .Consume();
    258    case layers::Animatable::TLengthPercentage:
    259      return Servo_AnimationValue_OffsetDistance(
    260                 &aAnimatable.get_LengthPercentage())
    261          .Consume();
    262    case layers::Animatable::TStyleOffsetRotate:
    263      return Servo_AnimationValue_OffsetRotate(
    264                 &aAnimatable.get_StyleOffsetRotate())
    265          .Consume();
    266    case layers::Animatable::TStylePositionOrAuto:
    267      return Servo_AnimationValue_OffsetAnchor(
    268                 &aAnimatable.get_StylePositionOrAuto())
    269          .Consume();
    270    case layers::Animatable::TStyleOffsetPosition:
    271      return Servo_AnimationValue_OffsetPosition(
    272                 &aAnimatable.get_StyleOffsetPosition())
    273          .Consume();
    274    default:
    275      MOZ_ASSERT_UNREACHABLE("Unsupported type");
    276  }
    277  return nullptr;
    278 }