Bug 1546894 - Keep track of current and begin points in path objects in case we'll create a builder from them. r=lsalzman

Because of the way the canvas 2D implementation juggles between path builders and paths, we have to keep track of current and first points in the path, in case a builder is created out of it.

Differential Revision: https://phabricator.services.mozilla.com/D33757

--HG--
extra : source : c79b3af2395894b449731fccdd9eb006b4d0189e
This commit is contained in:
Nicolas Silva 2019-06-05 09:55:46 +02:00
Родитель 5e669cb7bb
Коммит c44ff5af9a
14 изменённых файлов: 103 добавлений и 58 удалений

Просмотреть файл

@ -587,10 +587,31 @@ class PathSink : public RefCounted<PathSink> {
/** Add an arc to the current figure */
virtual void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
float aEndAngle, bool aAntiClockwise = false) = 0;
virtual Point CurrentPoint() const {
return mCurrentPoint;
}
virtual Point BeginPoint() const {
return mBeginPoint;
}
virtual void SetCurrentPoint(const Point& aPoint) {
mCurrentPoint = aPoint;
}
virtual void SetBeginPoint(const Point& aPoint) {
mBeginPoint = aPoint;
}
protected:
/** Point the current subpath is at - or where the next subpath will start
* if there is no active subpath.
*/
virtual Point CurrentPoint() const = 0;
Point mCurrentPoint;
/** Position of the previous MoveTo operation. */
Point mBeginPoint;
};
class PathBuilder;

Просмотреть файл

@ -75,7 +75,7 @@ void FlattenedPath::MoveTo(const Point& aPoint) {
op.mPoint = aPoint;
mPathOps.push_back(op);
mLastMove = aPoint;
mBeginPoint = aPoint;
}
void FlattenedPath::LineTo(const Point& aPoint) {
@ -109,7 +109,7 @@ void FlattenedPath::QuadraticBezierTo(const Point& aCP1, const Point& aCP2) {
void FlattenedPath::Close() {
MOZ_ASSERT(!mCalculatedLength);
LineTo(mLastMove);
LineTo(mBeginPoint);
}
void FlattenedPath::Arc(const Point& aOrigin, float aRadius, float aStartAngle,

Просмотреть файл

@ -45,7 +45,6 @@ class FlattenedPath : public PathSink {
private:
Float mCachedLength;
bool mCalculatedLength;
Point mLastMove;
std::vector<FlatPathOp> mPathOps;
};

Просмотреть файл

@ -102,18 +102,18 @@ void PathBuilderCairo::Arc(const Point& aOrigin, float aRadius,
aAntiClockwise);
}
Point PathBuilderCairo::CurrentPoint() const { return mCurrentPoint; }
already_AddRefed<Path> PathBuilderCairo::Finish() {
return MakeAndAddRef<PathCairo>(mFillRule, mPathData, mCurrentPoint);
return MakeAndAddRef<PathCairo>(mFillRule, mPathData, mCurrentPoint, mBeginPoint);
}
PathCairo::PathCairo(FillRule aFillRule,
std::vector<cairo_path_data_t>& aPathData,
const Point& aCurrentPoint)
const Point& aCurrentPoint,
const Point& aBeginPoint)
: mFillRule(aFillRule),
mContainingContext(nullptr),
mCurrentPoint(aCurrentPoint) {
mCurrentPoint(aCurrentPoint),
mBeginPoint(aBeginPoint) {
mPathData.swap(aPathData);
}
@ -143,6 +143,7 @@ already_AddRefed<PathBuilder> PathCairo::CopyToBuilder(
builder->mPathData = mPathData;
builder->mCurrentPoint = mCurrentPoint;
builder->mBeginPoint = mBeginPoint;
return builder.forget();
}
@ -153,6 +154,7 @@ already_AddRefed<PathBuilder> PathCairo::TransformedCopyToBuilder(
AppendPathToBuilder(builder, &aTransform);
builder->mCurrentPoint = aTransform.TransformPoint(mCurrentPoint);
builder->mBeginPoint = aTransform.TransformPoint(mBeginPoint);
return builder.forget();
}

Просмотреть файл

@ -30,7 +30,6 @@ class PathBuilderCairo : public PathBuilder {
void Close() override;
void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
float aEndAngle, bool aAntiClockwise = false) override;
Point CurrentPoint() const override;
already_AddRefed<Path> Finish() override;
BackendType GetBackendType() const override { return BackendType::CAIRO; }
@ -40,10 +39,6 @@ class PathBuilderCairo : public PathBuilder {
FillRule mFillRule;
std::vector<cairo_path_data_t> mPathData;
// It's easiest to track this here, parsing the path data to find the current
// point is a little tricky.
Point mCurrentPoint;
Point mBeginPoint;
};
class PathCairo : public Path {
@ -51,7 +46,7 @@ class PathCairo : public Path {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathCairo, override)
PathCairo(FillRule aFillRule, std::vector<cairo_path_data_t>& aPathData,
const Point& aCurrentPoint);
const Point& aCurrentPoint, const Point& aBeginPoint);
explicit PathCairo(cairo_t* aContext);
virtual ~PathCairo();
@ -91,6 +86,7 @@ class PathCairo : public Path {
mutable cairo_t* mContainingContext;
mutable Matrix mContainingTransform;
Point mCurrentPoint;
Point mBeginPoint;
};
} // namespace gfx

Просмотреть файл

@ -17,7 +17,7 @@ void PathBuilderCapture::MoveTo(const Point& aPoint) {
op.mP1 = aPoint;
mPathOps.push_back(op);
mCurrentPoint = aPoint;
mFirstPoint = aPoint;
mBeginPoint = aPoint;
}
void PathBuilderCapture::LineTo(const Point& aPoint) {
@ -68,16 +68,16 @@ void PathBuilderCapture::Close() {
PathOp op;
op.mType = PathOp::OP_CLOSE;
mPathOps.push_back(op);
mCurrentPoint = mFirstPoint;
mCurrentPoint = mBeginPoint;
}
Point PathBuilderCapture::CurrentPoint() const { return mCurrentPoint; }
already_AddRefed<Path> PathBuilderCapture::Finish() {
Point currentPoint = mCurrentPoint;
Point beginPoint = mBeginPoint;
mCurrentPoint = Point(0.0, 0.0);
mFirstPoint = Point(0.0, 0.0);
mBeginPoint = Point(0.0, 0.0);
return MakeAndAddRef<PathCapture>(std::move(mPathOps), mFillRule, mDT,
mCurrentPoint);
currentPoint, beginPoint);
}
already_AddRefed<PathBuilder> PathCapture::CopyToBuilder(
@ -85,6 +85,7 @@ already_AddRefed<PathBuilder> PathCapture::CopyToBuilder(
RefPtr<PathBuilderCapture> capture = new PathBuilderCapture(aFillRule, mDT);
capture->mPathOps = mPathOps;
capture->mCurrentPoint = mCurrentPoint;
capture->mBeginPoint = mBeginPoint;
return capture.forget();
}
@ -136,6 +137,7 @@ already_AddRefed<PathBuilder> PathCapture::TransformedCopyToBuilder(
}
}
capture->mCurrentPoint = aTransform.TransformPoint(mCurrentPoint);
capture->mBeginPoint = aTransform.TransformPoint(mBeginPoint);
return capture.forget();
}
bool PathCapture::ContainsPoint(const Point& aPoint,

Просмотреть файл

@ -45,11 +45,6 @@ class PathBuilderCapture : public PathBuilder {
*/
virtual void Close() override;
/* Point the current subpath is at - or where the next subpath will start
* if there is no active subpath.
*/
virtual Point CurrentPoint() const override;
virtual already_AddRefed<Path> Finish() override;
virtual BackendType GetBackendType() const override {
@ -61,8 +56,6 @@ class PathBuilderCapture : public PathBuilder {
FillRule mFillRule;
std::vector<PathOp> mPathOps;
Point mCurrentPoint;
Point mFirstPoint;
RefPtr<DrawTarget> mDT;
};
@ -71,11 +64,13 @@ class PathCapture : public Path {
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathCapture, override)
PathCapture(const std::vector<PathOp> aOps, FillRule aFillRule,
DrawTarget* aDT, const Point& aCurrentPoint)
DrawTarget* aDT, const Point& aCurrentPoint,
const Point& aBeginPoint)
: mPathOps(aOps),
mFillRule(aFillRule),
mDT(aDT),
mCurrentPoint(aCurrentPoint) {}
mCurrentPoint(aCurrentPoint),
mBeginPoint(aBeginPoint) {}
virtual BackendType GetBackendType() const override {
return BackendType::CAPTURE;
@ -110,6 +105,7 @@ class PathCapture : public Path {
FillRule mFillRule;
RefPtr<DrawTarget> mDT;
Point mCurrentPoint;
Point mBeginPoint;
};
} // namespace gfx

Просмотреть файл

@ -223,8 +223,6 @@ void PathBuilderD2D::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle,
mCurrentPoint = endPoint;
}
Point PathBuilderD2D::CurrentPoint() const { return mCurrentPoint; }
void PathBuilderD2D::EnsureActive(const Point& aPoint) {
if (!mFigureActive) {
mSink->BeginFigure(D2DPoint(aPoint), D2D1_FIGURE_BEGIN_FILLED);

Просмотреть файл

@ -36,7 +36,6 @@ class PathBuilderD2D : public PathBuilder {
virtual void Close();
virtual void Arc(const Point& aOrigin, Float aRadius, Float aStartAngle,
Float aEndAngle, bool aAntiClockwise = false);
virtual Point CurrentPoint() const;
virtual already_AddRefed<Path> Finish();
@ -55,8 +54,6 @@ class PathBuilderD2D : public PathBuilder {
RefPtr<ID2D1PathGeometry> mGeometry;
bool mFigureActive;
Point mCurrentPoint;
Point mBeginPoint;
FillRule mFillRule;
BackendType mBackendType;
};

Просмотреть файл

@ -57,13 +57,9 @@ void PathBuilderRecording::Close() {
mPathBuilder->Close();
}
Point PathBuilderRecording::CurrentPoint() const {
return mPathBuilder->CurrentPoint();
}
already_AddRefed<Path> PathBuilderRecording::Finish() {
RefPtr<Path> path = mPathBuilder->Finish();
return MakeAndAddRef<PathRecording>(path, mPathOps, mFillRule);
return MakeAndAddRef<PathRecording>(path, mPathOps, mFillRule, mCurrentPoint, mBeginPoint);
}
PathRecording::~PathRecording() {
@ -79,6 +75,8 @@ already_AddRefed<PathBuilder> PathRecording::CopyToBuilder(
RefPtr<PathBuilderRecording> recording =
new PathBuilderRecording(pathBuilder, aFillRule);
recording->mPathOps = mPathOps;
recording->SetCurrentPoint(mCurrentPoint);
recording->SetBeginPoint(mBeginPoint);
return recording.forget();
}
@ -104,6 +102,10 @@ already_AddRefed<PathBuilder> PathRecording::TransformedCopyToBuilder(
}
recording->mPathOps.push_back(newPathOp);
}
recording->SetCurrentPoint(aTransform.TransformPoint(mCurrentPoint));
recording->SetBeginPoint(aTransform.TransformPoint(mBeginPoint));
return recording.forget();
}

Просмотреть файл

@ -53,7 +53,21 @@ class PathBuilderRecording : public PathBuilder {
/* Point the current subpath is at - or where the next subpath will start
* if there is no active subpath.
*/
virtual Point CurrentPoint() const override;
virtual Point CurrentPoint() const override {
return mPathBuilder->CurrentPoint();
}
virtual Point BeginPoint() const override {
return mPathBuilder->BeginPoint();
}
virtual void SetCurrentPoint(const Point& aPoint) override {
mPathBuilder->SetCurrentPoint(aPoint);
}
virtual void SetBeginPoint(const Point& aPoint) override {
mPathBuilder->SetBeginPoint(aPoint);
}
virtual already_AddRefed<Path> Finish() override;
@ -73,8 +87,10 @@ class PathRecording : public Path {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathRecording, override)
PathRecording(Path* aPath, const std::vector<PathOp> aOps, FillRule aFillRule)
: mPath(aPath), mPathOps(aOps), mFillRule(aFillRule) {}
PathRecording(Path* aPath, const std::vector<PathOp> aOps, FillRule aFillRule,
const Point& aCurrentPoint, const Point& aBeginPoint)
: mPath(aPath), mPathOps(aOps), mFillRule(aFillRule),
mCurrentPoint(aCurrentPoint), mBeginPoint(aBeginPoint) {}
~PathRecording();
@ -122,6 +138,8 @@ class PathRecording : public Path {
RefPtr<Path> mPath;
std::vector<PathOp> mPathOps;
FillRule mFillRule;
Point mCurrentPoint;
Point mBeginPoint;
// Event recorders that have this path in their event stream.
std::vector<RefPtr<DrawEventRecorderPrivate>> mStoredRecorders;

Просмотреть файл

@ -37,7 +37,7 @@ void PathBuilderSkia::SetFillRule(FillRule aFillRule) {
void PathBuilderSkia::MoveTo(const Point& aPoint) {
mPath.moveTo(SkFloatToScalar(aPoint.x), SkFloatToScalar(aPoint.y));
mCurrentPoint = aPoint;
mFirstPoint = aPoint;
mBeginPoint = aPoint;
}
void PathBuilderSkia::LineTo(const Point& aPoint) {
@ -71,7 +71,7 @@ void PathBuilderSkia::QuadraticBezierTo(const Point& aCP1, const Point& aCP2) {
void PathBuilderSkia::Close() {
mPath.close();
mCurrentPoint = mFirstPoint;
mCurrentPoint = mBeginPoint;
}
void PathBuilderSkia::Arc(const Point& aOrigin, float aRadius,
@ -81,12 +81,12 @@ void PathBuilderSkia::Arc(const Point& aOrigin, float aRadius,
aAntiClockwise);
}
Point PathBuilderSkia::CurrentPoint() const { return mCurrentPoint; }
already_AddRefed<Path> PathBuilderSkia::Finish() {
RefPtr<Path> path = MakeAndAddRef<PathSkia>(mPath, mFillRule,
mCurrentPoint, mBeginPoint);
mCurrentPoint = Point(0.0, 0.0);
mFirstPoint = Point(0.0, 0.0);
return MakeAndAddRef<PathSkia>(mPath, mFillRule);
mBeginPoint = Point(0.0, 0.0);
return path.forget();
}
void PathBuilderSkia::AppendPath(const SkPath& aPath) { mPath.addPath(aPath); }
@ -98,7 +98,13 @@ already_AddRefed<PathBuilder> PathSkia::CopyToBuilder(
already_AddRefed<PathBuilder> PathSkia::TransformedCopyToBuilder(
const Matrix& aTransform, FillRule aFillRule) const {
return MakeAndAddRef<PathBuilderSkia>(aTransform, mPath, aFillRule);
RefPtr<PathBuilderSkia> builder = MakeAndAddRef<PathBuilderSkia>(
aTransform, mPath, aFillRule);
builder->mCurrentPoint = aTransform.TransformPoint(mCurrentPoint);
builder->mBeginPoint = aTransform.TransformPoint(mBeginPoint);
return builder.forget();
}
static bool SkPathContainsPoint(const SkPath& aPath, const Point& aPoint,

Просмотреть файл

@ -31,7 +31,6 @@ class PathBuilderSkia : public PathBuilder {
void Close() override;
void Arc(const Point& aOrigin, float aRadius, float aStartAngle,
float aEndAngle, bool aAntiClockwise = false) override;
Point CurrentPoint() const override;
already_AddRefed<Path> Finish() override;
void AppendPath(const SkPath& aPath);
@ -39,11 +38,11 @@ class PathBuilderSkia : public PathBuilder {
BackendType GetBackendType() const override { return BackendType::SKIA; }
private:
friend class PathSkia;
void SetFillRule(FillRule aFillRule);
SkPath mPath;
Point mCurrentPoint;
Point mFirstPoint;
FillRule mFillRule;
};
@ -51,7 +50,13 @@ class PathSkia : public Path {
public:
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathSkia, override)
PathSkia(SkPath& aPath, FillRule aFillRule) : mFillRule(aFillRule) {
PathSkia(SkPath& aPath,
FillRule aFillRule,
Point aCurrentPoint = Point(),
Point aBeginPoint = Point())
: mFillRule(aFillRule)
, mCurrentPoint(aCurrentPoint)
, mBeginPoint(aBeginPoint) {
mPath.swap(aPath);
}
@ -85,6 +90,8 @@ class PathSkia : public Path {
SkPath mPath;
FillRule mFillRule;
Point mCurrentPoint;
Point mBeginPoint;
};
} // namespace gfx

Просмотреть файл

@ -809,6 +809,7 @@ class SystemCairoClipper : public ClipExporter {
void MoveTo(const Point& aPoint) override {
cairo_move_to(mContext, aPoint.x / mScaleFactor, aPoint.y / mScaleFactor);
mBeginPoint = aPoint;
mCurrentPoint = aPoint;
}
@ -842,15 +843,15 @@ class SystemCairoClipper : public ClipExporter {
aAntiClockwise);
}
void Close() override { cairo_close_path(mContext); }
void Close() override {
cairo_close_path(mContext);
mCurrentPoint = mBeginPoint;
}
void EndClip() override { cairo_clip(mContext); }
Point CurrentPoint() const override { return mCurrentPoint; }
private:
cairo_t* mContext;
Point mCurrentPoint;
gint mScaleFactor;
};