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_GFX_PATHRECORDING_H_
8 #define MOZILLA_GFX_PATHRECORDING_H_
14 #include "PathHelpers.h"
15 #include "RecordingTypes.h"
36 explicit PathOps(S
& aStream
);
38 PathOps(const PathOps
& aOther
) = default;
39 PathOps
& operator=(const PathOps
&) = delete; // assign using std::move()!
41 PathOps(PathOps
&& aOther
) = default;
42 PathOps
& operator=(PathOps
&& aOther
) = default;
45 void Record(S
& aStream
) const;
47 bool StreamToSink(PathSink
& aPathSink
) const;
49 bool CheckedStreamToSink(PathSink
& aPathSink
) const;
51 PathOps
TransformedCopy(const Matrix
& aTransform
) const;
53 size_t NumberOfOps() const;
55 void MoveTo(const Point
& aPoint
) { AppendPathOp(OpType::OP_MOVETO
, aPoint
); }
57 void LineTo(const Point
& aPoint
) { AppendPathOp(OpType::OP_LINETO
, aPoint
); }
59 void BezierTo(const Point
& aCP1
, const Point
& aCP2
, const Point
& aCP3
) {
60 AppendPathOp(OpType::OP_BEZIERTO
, ThreePoints
{aCP1
, aCP2
, aCP3
});
63 void QuadraticBezierTo(const Point
& aCP1
, const Point
& aCP2
) {
64 AppendPathOp(OpType::OP_QUADRATICBEZIERTO
, TwoPoints
{aCP1
, aCP2
});
67 void Arc(const Point
& aOrigin
, float aRadius
, float aStartAngle
,
68 float aEndAngle
, bool aAntiClockwise
) {
69 AppendPathOp(OpType::OP_ARC
, ArcParams
{aOrigin
, aRadius
, aStartAngle
,
70 aEndAngle
, aAntiClockwise
});
74 size_t oldSize
= mPathData
.size();
75 mPathData
.resize(oldSize
+ sizeof(OpType
));
76 *reinterpret_cast<OpType
*>(mPathData
.data() + oldSize
) = OpType::OP_CLOSE
;
79 Maybe
<Circle
> AsCircle() const;
80 Maybe
<Line
> AsLine() const;
82 bool IsActive() const { return !mPathData
.empty(); }
87 enum class OpType
: uint32_t {
98 void AppendPathOp(const OpType
& aOpType
, const T
& aOpParams
) {
99 size_t oldSize
= mPathData
.size();
100 mPathData
.resize(oldSize
+ sizeof(OpType
) + sizeof(T
));
101 memcpy(mPathData
.data() + oldSize
, &aOpType
, sizeof(OpType
));
102 oldSize
+= sizeof(OpType
);
103 memcpy(mPathData
.data() + oldSize
, &aOpParams
, sizeof(T
));
125 std::vector
<uint8_t> mPathData
;
129 PathOps::PathOps(S
& aStream
) {
130 ReadVector(aStream
, mPathData
);
134 inline void PathOps::Record(S
& aStream
) const {
135 WriteVector(aStream
, mPathData
);
139 class DrawEventRecorderPrivate
;
141 class PathBuilderRecording final
: public PathBuilder
{
143 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathBuilderRecording
, override
)
145 PathBuilderRecording(BackendType aBackend
, FillRule aFillRule
)
146 : mBackendType(aBackend
), mFillRule(aFillRule
) {}
148 PathBuilderRecording(BackendType aBackend
, PathOps
&& aPathOps
,
150 : mBackendType(aBackend
),
151 mFillRule(aFillRule
),
152 mPathOps(std::move(aPathOps
)) {}
154 /* Move the current point in the path, any figure currently being drawn will
155 * be considered closed during fill operations, however when stroking the
156 * closing line segment will not be drawn.
158 void MoveTo(const Point
& aPoint
) final
;
160 /* Add a linesegment to the current figure */
161 void LineTo(const Point
& aPoint
) final
;
163 /* Add a cubic bezier curve to the current figure */
164 void BezierTo(const Point
& aCP1
, const Point
& aCP2
, const Point
& aCP3
) final
;
166 /* Add a quadratic bezier curve to the current figure */
167 void QuadraticBezierTo(const Point
& aCP1
, const Point
& aCP2
) final
;
169 /* Close the current figure, this will essentially generate a line segment
170 * from the current point to the starting point for the current figure
174 /* Add an arc to the current figure */
175 void Arc(const Point
& aOrigin
, float aRadius
, float aStartAngle
,
176 float aEndAngle
, bool aAntiClockwise
) final
;
178 already_AddRefed
<Path
> Finish() final
;
180 BackendType
GetBackendType() const final
{ return BackendType::RECORDING
; }
182 bool IsActive() const final
{ return mPathOps
.IsActive(); }
185 BackendType mBackendType
;
190 class PathRecording final
: public Path
{
192 MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathRecording
, override
)
194 PathRecording(BackendType aBackend
, PathOps
&& aOps
, FillRule aFillRule
,
195 const Point
& aCurrentPoint
, const Point
& aBeginPoint
);
199 BackendType
GetBackendType() const final
{ return BackendType::RECORDING
; }
200 already_AddRefed
<PathBuilder
> CopyToBuilder(FillRule aFillRule
) const final
;
201 already_AddRefed
<PathBuilder
> TransformedCopyToBuilder(
202 const Matrix
& aTransform
, FillRule aFillRule
) const final
;
203 bool ContainsPoint(const Point
& aPoint
,
204 const Matrix
& aTransform
) const final
{
206 return mPath
->ContainsPoint(aPoint
, aTransform
);
208 bool StrokeContainsPoint(const StrokeOptions
& aStrokeOptions
,
210 const Matrix
& aTransform
) const final
{
212 return mPath
->StrokeContainsPoint(aStrokeOptions
, aPoint
, aTransform
);
215 Rect
GetBounds(const Matrix
& aTransform
= Matrix()) const final
{
217 return mPath
->GetBounds(aTransform
);
220 Rect
GetStrokedBounds(const StrokeOptions
& aStrokeOptions
,
221 const Matrix
& aTransform
= Matrix()) const final
{
223 return mPath
->GetStrokedBounds(aStrokeOptions
, aTransform
);
226 Maybe
<Rect
> AsRect() const final
{
228 return mPath
->AsRect();
231 Maybe
<Circle
> AsCircle() const { return mPathOps
.AsCircle(); }
232 Maybe
<Line
> AsLine() const { return mPathOps
.AsLine(); }
234 void StreamToSink(PathSink
* aSink
) const final
{
235 mPathOps
.StreamToSink(*aSink
);
238 FillRule
GetFillRule() const final
{ return mFillRule
; }
240 bool IsEmpty() const final
{ return mPathOps
.IsEmpty(); }
243 friend class DrawTargetWrapAndRecord
;
244 friend class DrawTargetRecording
;
245 friend class RecordedPathCreation
;
247 void EnsurePath() const;
249 BackendType mBackendType
;
250 mutable RefPtr
<Path
> mPath
;
256 // Event recorders that have this path in their event stream.
257 std::vector
<RefPtr
<DrawEventRecorderPrivate
>> mStoredRecorders
;
261 } // namespace mozilla
263 #endif /* MOZILLA_GFX_PATHRECORDING_H_ */