tor-browser

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

MotionPathUtils.h (8921B)


      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 #ifndef mozilla_MotionPathUtils_h
      8 #define mozilla_MotionPathUtils_h
      9 
     10 #include "Units.h"
     11 #include "mozilla/Maybe.h"
     12 #include "mozilla/ServoStyleConsts.h"
     13 #include "mozilla/gfx/2D.h"
     14 #include "mozilla/gfx/Point.h"
     15 #include "mozilla/gfx/Rect.h"
     16 
     17 class nsIFrame;
     18 
     19 namespace nsStyleTransformMatrix {
     20 class TransformReferenceBox;
     21 }
     22 
     23 namespace mozilla {
     24 
     25 namespace layers {
     26 class MotionPathData;
     27 class PathCommand;
     28 }  // namespace layers
     29 
     30 struct ResolvedMotionPathData {
     31  gfx::Point mTranslate;
     32  float mRotate;
     33  // The delta value between transform-origin and offset-anchor.
     34  gfx::Point mShift;
     35 };
     36 
     37 // The collected information for offset-path. We preprocess the value of
     38 // offset-path and use this data for resolving motion path.
     39 struct OffsetPathData {
     40  enum class Type : uint8_t {
     41    None,
     42    Shape,
     43    Ray,
     44  };
     45 
     46  struct ShapeData {
     47    RefPtr<gfx::Path> mGfxPath;
     48    // The current position of this transfromed box in the coordinate system of
     49    // its containing block.
     50    nsPoint mCurrentPosition;
     51    // True if it is a closed loop; false if it is a unclosed interval.
     52    // https://drafts.fxtf.org/motion/#path-distance
     53    bool mIsClosedLoop;
     54  };
     55 
     56  struct RayData {
     57    const StyleRayFunction* mRay;
     58    // The coord box of the containing block.
     59    nsRect mCoordBox;
     60    // The current position of this transfromed box in the coordinate system of
     61    // its containing block.
     62    nsPoint mCurrentPosition;
     63    // The reference length for computing ray(contain).
     64    CSSCoord mContainReferenceLength;
     65  };
     66 
     67  Type mType;
     68  union {
     69    ShapeData mShape;
     70    RayData mRay;
     71  };
     72 
     73  static OffsetPathData None() { return OffsetPathData(); }
     74  static OffsetPathData Shape(already_AddRefed<gfx::Path>&& aGfxPath,
     75                              nsPoint&& aCurrentPosition, bool aIsClosedPath) {
     76    return OffsetPathData(std::move(aGfxPath), std::move(aCurrentPosition),
     77                          aIsClosedPath);
     78  }
     79  static OffsetPathData Ray(const StyleRayFunction& aRay, nsRect&& aCoordBox,
     80                            nsPoint&& aPosition,
     81                            CSSCoord&& aContainReferenceLength) {
     82    return OffsetPathData(&aRay, std::move(aCoordBox), std::move(aPosition),
     83                          std::move(aContainReferenceLength));
     84  }
     85  static OffsetPathData Ray(const StyleRayFunction& aRay,
     86                            const nsRect& aCoordBox, const nsPoint& aPosition,
     87                            const CSSCoord& aContainReferenceLength) {
     88    return OffsetPathData(&aRay, aCoordBox, aPosition, aContainReferenceLength);
     89  }
     90 
     91  bool IsNone() const { return mType == Type::None; }
     92  bool IsShape() const { return mType == Type::Shape; }
     93  bool IsRay() const { return mType == Type::Ray; }
     94 
     95  const ShapeData& AsShape() const {
     96    MOZ_ASSERT(IsShape());
     97    return mShape;
     98  }
     99 
    100  const RayData& AsRay() const {
    101    MOZ_ASSERT(IsRay());
    102    return mRay;
    103  }
    104 
    105  ~OffsetPathData() {
    106    switch (mType) {
    107      case Type::Shape:
    108        mShape.~ShapeData();
    109        break;
    110      case Type::Ray:
    111        mRay.~RayData();
    112        break;
    113      default:
    114        break;
    115    }
    116  }
    117 
    118  OffsetPathData(const OffsetPathData& aOther) : mType(aOther.mType) {
    119    switch (mType) {
    120      case Type::Shape:
    121        mShape = aOther.mShape;
    122        break;
    123      case Type::Ray:
    124        mRay = aOther.mRay;
    125        break;
    126      default:
    127        break;
    128    }
    129  }
    130 
    131  OffsetPathData(OffsetPathData&& aOther) : mType(aOther.mType) {
    132    switch (mType) {
    133      case Type::Shape:
    134        mShape = std::move(aOther.mShape);
    135        break;
    136      case Type::Ray:
    137        mRay = std::move(aOther.mRay);
    138        break;
    139      default:
    140        break;
    141    }
    142  }
    143 
    144 private:
    145  OffsetPathData() : mType(Type::None) {}
    146  OffsetPathData(already_AddRefed<gfx::Path>&& aPath,
    147                 nsPoint&& aCurrentPosition, bool aIsClosed)
    148      : mType(Type::Shape),
    149        mShape{std::move(aPath), std::move(aCurrentPosition), aIsClosed} {}
    150  OffsetPathData(const StyleRayFunction* aRay, nsRect&& aCoordBox,
    151                 nsPoint&& aPosition, CSSCoord&& aContainReferenceLength)
    152      : mType(Type::Ray),
    153        mRay{aRay, std::move(aCoordBox), std::move(aPosition),
    154             std::move(aContainReferenceLength)} {}
    155  OffsetPathData(const StyleRayFunction* aRay, const nsRect& aCoordBox,
    156                 const nsPoint& aPosition,
    157                 const CSSCoord& aContainReferenceLength)
    158      : mType(Type::Ray),
    159        mRay{aRay, aCoordBox, aPosition, aContainReferenceLength} {}
    160  OffsetPathData& operator=(const OffsetPathData&) = delete;
    161  OffsetPathData& operator=(OffsetPathData&&) = delete;
    162 };
    163 
    164 // MotionPathUtils is a namespace class containing utility functions related to
    165 // processing motion path in the [motion-1].
    166 // https://drafts.fxtf.org/motion-1/
    167 class MotionPathUtils final {
    168  using TransformReferenceBox = nsStyleTransformMatrix::TransformReferenceBox;
    169 
    170 public:
    171  /**
    172   * SVG frames (unlike other frames) have a reference box that can be (and
    173   * typically is) offset from the TopLeft() of the frame.
    174   *
    175   * In motion path, we have to make sure the object is aligned with offset-path
    176   * when using content area, so we should tweak the anchor point by a given
    177   * offset.
    178   */
    179  static CSSPoint ComputeAnchorPointAdjustment(const nsIFrame& aFrame);
    180 
    181  /**
    182   * In CSS context, this returns the the box being referenced from the element
    183   * that establishes the containing block for this element.
    184   * In SVG context, we always use view-box.
    185   * https://drafts.fxtf.org/motion-1/#valdef-offset-path-coord-box
    186   */
    187  static const nsIFrame* GetOffsetPathReferenceBox(const nsIFrame* aFrame,
    188                                                   nsRect& aOutputRect);
    189 
    190  /**
    191   * Return the width or the height of the element’s border box, whichever is
    192   * larger. This is for computing the ray() with "contain" keyword.
    193   */
    194  static CSSCoord GetRayContainReferenceSize(nsIFrame* aFrame);
    195 
    196  /**
    197   * Get the resolved radius for inset(0 round X), where X is the parameter of
    198   * |aRadius|.
    199   * This returns an empty array if we cannot compute the radii; otherwise, it
    200   * returns an array with 8 elements.
    201   */
    202  static nsTArray<nscoord> ComputeBorderRadii(
    203      const StyleBorderRadius& aBorderRadius, const nsRect& aCoordBox);
    204 
    205  /**
    206   * Generate the motion path transform result. This function may be called on
    207   * the compositor thread.
    208   */
    209  static Maybe<ResolvedMotionPathData> ResolveMotionPath(
    210      const OffsetPathData& aPath, const LengthPercentage& aDistance,
    211      const StyleOffsetRotate& aRotate, const StylePositionOrAuto& aAnchor,
    212      const StyleOffsetPosition& aPosition, const CSSPoint& aTransformOrigin,
    213      TransformReferenceBox&, const CSSPoint& aAnchorPointAdjustment);
    214 
    215  /**
    216   * Generate the motion path transform result with |nsIFrame|. This is only
    217   * called in the main thread.
    218   */
    219  static Maybe<ResolvedMotionPathData> ResolveMotionPath(
    220      const nsIFrame* aFrame, TransformReferenceBox&);
    221 
    222  /**
    223   * Generate the motion path transfrom result with styles and
    224   * layers::MotionPathData.
    225   * This is only called by the compositor.
    226   */
    227  static Maybe<ResolvedMotionPathData> ResolveMotionPath(
    228      const StyleOffsetPath* aPath, const StyleLengthPercentage* aDistance,
    229      const StyleOffsetRotate* aRotate, const StylePositionOrAuto* aAnchor,
    230      const StyleOffsetPosition* aPosition,
    231      const Maybe<layers::MotionPathData>& aMotionPathData,
    232      TransformReferenceBox&, gfx::Path* aCachedMotionPath);
    233 
    234  /**
    235   * Build a gfx::Path from the svg path data. We should give it a path builder.
    236   * If |aPathBuilder| is nullptr, we return null path.
    237   * This can be used on the main thread or on the compositor thread.
    238   */
    239  static already_AddRefed<gfx::Path> BuildSVGPath(
    240      const StyleSVGPathData& aPath, gfx::PathBuilder* aPathBuilder);
    241 
    242  /**
    243   * Build a gfx::Path from the computed basic shape.
    244   */
    245  static already_AddRefed<gfx::Path> BuildPath(const StyleBasicShape&,
    246                                               const StyleOffsetPosition&,
    247                                               const nsRect& aCoordBox,
    248                                               const nsPoint& aCurrentPosition,
    249                                               gfx::PathBuilder*);
    250 
    251  /**
    252   * Get a path builder for motion path on the main thread.
    253   */
    254  static already_AddRefed<gfx::PathBuilder> GetPathBuilder();
    255 
    256  /**
    257   * Get a path builder for compositor.
    258   */
    259  static already_AddRefed<gfx::PathBuilder> GetCompositorPathBuilder();
    260 };
    261 
    262 }  // namespace mozilla
    263 
    264 #endif  // mozilla_MotionPathUtils_h