Bug 1646700 [wpt PR 24235] - Update picture-in-picture idlharness test, a=testonly
[gecko.git] / layout / base / MotionPathUtils.h
blob08b946801f12d209988e0147384325f33ce7d95e
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/Point.h"
11 #include "mozilla/Maybe.h"
12 #include "mozilla/ServoStyleConsts.h"
13 #include "Units.h"
15 class nsIFrame;
17 namespace nsStyleTransformMatrix {
18 class TransformReferenceBox;
21 namespace mozilla {
23 using RayFunction = StyleRayFunction<StyleAngle>;
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 struct RayReferenceData {
38 // The initial position related to the containing block.
39 CSSPoint mInitialPosition;
40 // The rect of the containing block.
41 CSSRect mContainingBlockRect;
43 RayReferenceData() = default;
44 explicit RayReferenceData(const nsIFrame* aFrame);
46 bool operator==(const RayReferenceData& aOther) const {
47 return mInitialPosition == aOther.mInitialPosition &&
48 mContainingBlockRect == aOther.mContainingBlockRect;
52 // The collected information for offset-path. We preprocess the value of
53 // offset-path and use this data for resolving motion path.
54 struct OffsetPathData {
55 enum class Type : uint8_t {
56 None,
57 Path,
58 Ray,
61 struct PathData {
62 RefPtr<gfx::Path> mGfxPath;
63 bool mIsClosedIntervals;
66 struct RayData {
67 const RayFunction* mRay;
68 RayReferenceData mData;
71 Type mType;
72 union {
73 PathData mPath;
74 RayData mRay;
77 static OffsetPathData None() { return OffsetPathData(); }
78 static OffsetPathData Path(const StyleSVGPathData& aPath,
79 already_AddRefed<gfx::Path>&& aGfxPath) {
80 const auto& path = aPath._0.AsSpan();
81 return OffsetPathData(std::move(aGfxPath),
82 !path.empty() && path.rbegin()->IsClosePath());
84 static OffsetPathData Ray(const RayFunction& aRay,
85 const RayReferenceData& aData) {
86 return OffsetPathData(&aRay, aData);
88 static OffsetPathData Ray(const RayFunction& aRay, RayReferenceData&& aData) {
89 return OffsetPathData(&aRay, std::move(aData));
92 bool IsNone() const { return mType == Type::None; }
93 bool IsPath() const { return mType == Type::Path; }
94 bool IsRay() const { return mType == Type::Ray; }
96 const PathData& AsPath() const {
97 MOZ_ASSERT(IsPath());
98 return mPath;
101 const RayData& AsRay() const {
102 MOZ_ASSERT(IsRay());
103 return mRay;
106 ~OffsetPathData() {
107 switch (mType) {
108 case Type::Path:
109 mPath.~PathData();
110 break;
111 case Type::Ray:
112 mRay.~RayData();
113 break;
114 default:
115 break;
119 OffsetPathData(const OffsetPathData& aOther) : mType(aOther.mType) {
120 switch (mType) {
121 case Type::Path:
122 mPath = aOther.mPath;
123 break;
124 case Type::Ray:
125 mRay = aOther.mRay;
126 break;
127 default:
128 break;
132 OffsetPathData(OffsetPathData&& aOther) : mType(aOther.mType) {
133 switch (mType) {
134 case Type::Path:
135 mPath = std::move(aOther.mPath);
136 break;
137 case Type::Ray:
138 mRay = std::move(aOther.mRay);
139 break;
140 default:
141 break;
145 private:
146 OffsetPathData() : mType(Type::None) {}
147 OffsetPathData(already_AddRefed<gfx::Path>&& aPath, bool aIsClosed)
148 : mType(Type::Path), mPath{std::move(aPath), aIsClosed} {}
149 OffsetPathData(const RayFunction* aRay, RayReferenceData&& aRef)
150 : mType(Type::Ray), mRay{aRay, std::move(aRef)} {}
151 OffsetPathData(const RayFunction* aRay, const RayReferenceData& aRef)
152 : mType(Type::Ray), mRay{aRay, aRef} {}
153 OffsetPathData& operator=(const OffsetPathData&) = delete;
154 OffsetPathData& operator=(OffsetPathData&&) = delete;
157 // MotionPathUtils is a namespace class containing utility functions related to
158 // processing motion path in the [motion-1].
159 // https://drafts.fxtf.org/motion-1/
160 class MotionPathUtils final {
161 using TransformReferenceBox = nsStyleTransformMatrix::TransformReferenceBox;
163 public:
164 // SVG frames (unlike other frames) have a reference box that can be (and
165 // typically is) offset from the TopLeft() of the frame.
167 // In motion path, we have to make sure the object is aligned with offset-path
168 // when using content area, so we should tweak the anchor point by a given
169 // offset.
170 static CSSPoint ComputeAnchorPointAdjustment(const nsIFrame& aFrame);
173 * Generate the motion path transform result. This function may be called on
174 * the compositor thread.
176 static Maybe<ResolvedMotionPathData> ResolveMotionPath(
177 const OffsetPathData& aPath, const LengthPercentage& aDistance,
178 const StyleOffsetRotate& aRotate, const StylePositionOrAuto& aAnchor,
179 const CSSPoint& aTransformOrigin, TransformReferenceBox&,
180 const CSSPoint& aAnchorPointAdjustment);
183 * Generate the motion path transform result with |nsIFrame|. This is only
184 * called in the main thread.
186 static Maybe<ResolvedMotionPathData> ResolveMotionPath(
187 const nsIFrame* aFrame, TransformReferenceBox&);
190 * Generate the motion path transfrom result with styles and
191 * layers::MotionPathData.
192 * This is only called by the compositor.
194 static Maybe<ResolvedMotionPathData> ResolveMotionPath(
195 const StyleOffsetPath* aPath, const StyleLengthPercentage* aDistance,
196 const StyleOffsetRotate* aRotate, const StylePositionOrAuto* aAnchor,
197 const Maybe<layers::MotionPathData>& aMotionPathData,
198 TransformReferenceBox&, gfx::Path* aCachedMotionPath);
201 * Normalize StyleSVGPathData.
203 * The algorithm of normalization is the same as normalize() in
204 * servo/components/style/values/specified/svg_path.rs
205 * FIXME: Bug 1489392: We don't have to normalize the path here if we accept
206 * the spec issue which would like to normalize svg paths at computed time.
207 * https://github.com/w3c/svgwg/issues/321
209 static StyleSVGPathData NormalizeSVGPathData(const StyleSVGPathData& aPath);
212 * Build a gfx::Path from the computed svg path. We should give it a path
213 * builder. If |aPathBuilder| is nullptr, we return null path.
214 * */
215 static already_AddRefed<gfx::Path> BuildPath(const StyleSVGPathData& aPath,
216 gfx::PathBuilder* aPathBuilder);
219 * Get a path builder for compositor.
221 static already_AddRefed<gfx::PathBuilder> GetCompositorPathBuilder();
224 } // namespace mozilla
226 #endif // mozilla_MotionPathUtils_h