Bug 1869043 allow a device to be specified with MediaTrackGraph::NotifyWhenDeviceStar...
[gecko.git] / layout / base / MotionPathUtils.h
blobcf4d820016897003c73097f8fc2468df0243f9ce
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/. */
7 #ifndef mozilla_MotionPathUtils_h
8 #define mozilla_MotionPathUtils_h
10 #include "mozilla/gfx/2D.h"
11 #include "mozilla/gfx/Point.h"
12 #include "mozilla/gfx/Rect.h"
13 #include "mozilla/Maybe.h"
14 #include "mozilla/ServoStyleConsts.h"
15 #include "Units.h"
17 class nsIFrame;
19 namespace nsStyleTransformMatrix {
20 class TransformReferenceBox;
23 namespace mozilla {
25 namespace layers {
26 class MotionPathData;
27 class PathCommand;
28 } // namespace layers
30 struct ResolvedMotionPathData {
31 gfx::Point mTranslate;
32 float mRotate;
33 // The delta value between transform-origin and offset-anchor.
34 gfx::Point mShift;
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,
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;
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;
67 Type mType;
68 union {
69 ShapeData mShape;
70 RayData mRay;
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);
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));
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);
91 bool IsNone() const { return mType == Type::None; }
92 bool IsShape() const { return mType == Type::Shape; }
93 bool IsRay() const { return mType == Type::Ray; }
95 const ShapeData& AsShape() const {
96 MOZ_ASSERT(IsShape());
97 return mShape;
100 const RayData& AsRay() const {
101 MOZ_ASSERT(IsRay());
102 return mRay;
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;
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;
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;
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;
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;
170 public:
172 * SVG frames (unlike other frames) have a reference box that can be (and
173 * typically is) offset from the TopLeft() of the frame.
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.
179 static CSSPoint ComputeAnchorPointAdjustment(const nsIFrame& aFrame);
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
187 static const nsIFrame* GetOffsetPathReferenceBox(const nsIFrame* aFrame,
188 nsRect& aOutputRect);
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.
194 static CSSCoord GetRayContainReferenceSize(nsIFrame* aFrame);
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.
202 static nsTArray<nscoord> ComputeBorderRadii(
203 const StyleBorderRadius& aBorderRadius, const nsRect& aCoordBox);
206 * Generate the motion path transform result. This function may be called on
207 * the compositor thread.
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);
216 * Generate the motion path transform result with |nsIFrame|. This is only
217 * called in the main thread.
219 static Maybe<ResolvedMotionPathData> ResolveMotionPath(
220 const nsIFrame* aFrame, TransformReferenceBox&);
223 * Generate the motion path transfrom result with styles and
224 * layers::MotionPathData.
225 * This is only called by the compositor.
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);
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.
239 static already_AddRefed<gfx::Path> BuildSVGPath(
240 const StyleSVGPathData& aPath, gfx::PathBuilder* aPathBuilder);
243 * Build a gfx::Path from the computed basic shape.
245 static already_AddRefed<gfx::Path> BuildPath(const StyleBasicShape&,
246 const StyleOffsetPosition&,
247 const nsRect& aCoordBox,
248 const nsPoint& aCurrentPosition,
249 gfx::PathBuilder*);
252 * Get a path builder for motion path on the main thread.
254 static already_AddRefed<gfx::PathBuilder> GetPathBuilder();
257 * Get a path builder for compositor.
259 static already_AddRefed<gfx::PathBuilder> GetCompositorPathBuilder();
262 } // namespace mozilla
264 #endif // mozilla_MotionPathUtils_h