From c44ff5af9a8ae46598490e9e1ee9d709ce319519 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Wed, 5 Jun 2019 09:55:46 +0200 Subject: [PATCH] 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 --- gfx/2d/2D.h | 23 ++++++++++++++++++++++- gfx/2d/Path.cpp | 4 ++-- gfx/2d/PathAnalysis.h | 1 - gfx/2d/PathCairo.cpp | 12 +++++++----- gfx/2d/PathCairo.h | 8 ++------ gfx/2d/PathCapture.cpp | 14 ++++++++------ gfx/2d/PathCapture.h | 14 +++++--------- gfx/2d/PathD2D.cpp | 2 -- gfx/2d/PathD2D.h | 3 --- gfx/2d/PathRecording.cpp | 12 +++++++----- gfx/2d/PathRecording.h | 24 +++++++++++++++++++++--- gfx/2d/PathSkia.cpp | 20 +++++++++++++------- gfx/2d/PathSkia.h | 15 +++++++++++---- widget/gtk/nsNativeThemeGTK.cpp | 9 +++++---- 14 files changed, 103 insertions(+), 58 deletions(-) diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h index fb3b1a8665a5..98bbf5f55816 100644 --- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -587,10 +587,31 @@ class PathSink : public RefCounted { /** 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; diff --git a/gfx/2d/Path.cpp b/gfx/2d/Path.cpp index 6b0357ed6e89..e7865c63e12f 100644 --- a/gfx/2d/Path.cpp +++ b/gfx/2d/Path.cpp @@ -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, diff --git a/gfx/2d/PathAnalysis.h b/gfx/2d/PathAnalysis.h index 1b89f29a9362..f162d962131f 100644 --- a/gfx/2d/PathAnalysis.h +++ b/gfx/2d/PathAnalysis.h @@ -45,7 +45,6 @@ class FlattenedPath : public PathSink { private: Float mCachedLength; bool mCalculatedLength; - Point mLastMove; std::vector mPathOps; }; diff --git a/gfx/2d/PathCairo.cpp b/gfx/2d/PathCairo.cpp index 1def9942be87..bddab619c2c5 100644 --- a/gfx/2d/PathCairo.cpp +++ b/gfx/2d/PathCairo.cpp @@ -102,18 +102,18 @@ void PathBuilderCairo::Arc(const Point& aOrigin, float aRadius, aAntiClockwise); } -Point PathBuilderCairo::CurrentPoint() const { return mCurrentPoint; } - already_AddRefed PathBuilderCairo::Finish() { - return MakeAndAddRef(mFillRule, mPathData, mCurrentPoint); + return MakeAndAddRef(mFillRule, mPathData, mCurrentPoint, mBeginPoint); } PathCairo::PathCairo(FillRule aFillRule, std::vector& 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 PathCairo::CopyToBuilder( builder->mPathData = mPathData; builder->mCurrentPoint = mCurrentPoint; + builder->mBeginPoint = mBeginPoint; return builder.forget(); } @@ -153,6 +154,7 @@ already_AddRefed PathCairo::TransformedCopyToBuilder( AppendPathToBuilder(builder, &aTransform); builder->mCurrentPoint = aTransform.TransformPoint(mCurrentPoint); + builder->mBeginPoint = aTransform.TransformPoint(mBeginPoint); return builder.forget(); } diff --git a/gfx/2d/PathCairo.h b/gfx/2d/PathCairo.h index 6ed079d742ad..dfdde8739ab3 100644 --- a/gfx/2d/PathCairo.h +++ b/gfx/2d/PathCairo.h @@ -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 Finish() override; BackendType GetBackendType() const override { return BackendType::CAIRO; } @@ -40,10 +39,6 @@ class PathBuilderCairo : public PathBuilder { FillRule mFillRule; std::vector 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& 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 diff --git a/gfx/2d/PathCapture.cpp b/gfx/2d/PathCapture.cpp index ae1aee54e309..9e33cfa10ee2 100644 --- a/gfx/2d/PathCapture.cpp +++ b/gfx/2d/PathCapture.cpp @@ -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 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(std::move(mPathOps), mFillRule, mDT, - mCurrentPoint); + currentPoint, beginPoint); } already_AddRefed PathCapture::CopyToBuilder( @@ -85,6 +85,7 @@ already_AddRefed PathCapture::CopyToBuilder( RefPtr capture = new PathBuilderCapture(aFillRule, mDT); capture->mPathOps = mPathOps; capture->mCurrentPoint = mCurrentPoint; + capture->mBeginPoint = mBeginPoint; return capture.forget(); } @@ -136,6 +137,7 @@ already_AddRefed PathCapture::TransformedCopyToBuilder( } } capture->mCurrentPoint = aTransform.TransformPoint(mCurrentPoint); + capture->mBeginPoint = aTransform.TransformPoint(mBeginPoint); return capture.forget(); } bool PathCapture::ContainsPoint(const Point& aPoint, diff --git a/gfx/2d/PathCapture.h b/gfx/2d/PathCapture.h index 595d7f439886..8237c661d3ef 100644 --- a/gfx/2d/PathCapture.h +++ b/gfx/2d/PathCapture.h @@ -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 Finish() override; virtual BackendType GetBackendType() const override { @@ -61,8 +56,6 @@ class PathBuilderCapture : public PathBuilder { FillRule mFillRule; std::vector mPathOps; - Point mCurrentPoint; - Point mFirstPoint; RefPtr mDT; }; @@ -71,11 +64,13 @@ class PathCapture : public Path { MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathCapture, override) PathCapture(const std::vector 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 mDT; Point mCurrentPoint; + Point mBeginPoint; }; } // namespace gfx diff --git a/gfx/2d/PathD2D.cpp b/gfx/2d/PathD2D.cpp index 7f657c6db2e5..c4bbd534af39 100644 --- a/gfx/2d/PathD2D.cpp +++ b/gfx/2d/PathD2D.cpp @@ -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); diff --git a/gfx/2d/PathD2D.h b/gfx/2d/PathD2D.h index 1423e27a8e02..db6cadc44210 100644 --- a/gfx/2d/PathD2D.h +++ b/gfx/2d/PathD2D.h @@ -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 Finish(); @@ -55,8 +54,6 @@ class PathBuilderD2D : public PathBuilder { RefPtr mGeometry; bool mFigureActive; - Point mCurrentPoint; - Point mBeginPoint; FillRule mFillRule; BackendType mBackendType; }; diff --git a/gfx/2d/PathRecording.cpp b/gfx/2d/PathRecording.cpp index 005add114429..4512a91543e2 100644 --- a/gfx/2d/PathRecording.cpp +++ b/gfx/2d/PathRecording.cpp @@ -57,13 +57,9 @@ void PathBuilderRecording::Close() { mPathBuilder->Close(); } -Point PathBuilderRecording::CurrentPoint() const { - return mPathBuilder->CurrentPoint(); -} - already_AddRefed PathBuilderRecording::Finish() { RefPtr path = mPathBuilder->Finish(); - return MakeAndAddRef(path, mPathOps, mFillRule); + return MakeAndAddRef(path, mPathOps, mFillRule, mCurrentPoint, mBeginPoint); } PathRecording::~PathRecording() { @@ -79,6 +75,8 @@ already_AddRefed PathRecording::CopyToBuilder( RefPtr recording = new PathBuilderRecording(pathBuilder, aFillRule); recording->mPathOps = mPathOps; + recording->SetCurrentPoint(mCurrentPoint); + recording->SetBeginPoint(mBeginPoint); return recording.forget(); } @@ -104,6 +102,10 @@ already_AddRefed PathRecording::TransformedCopyToBuilder( } recording->mPathOps.push_back(newPathOp); } + + recording->SetCurrentPoint(aTransform.TransformPoint(mCurrentPoint)); + recording->SetBeginPoint(aTransform.TransformPoint(mBeginPoint)); + return recording.forget(); } diff --git a/gfx/2d/PathRecording.h b/gfx/2d/PathRecording.h index fea2a144a7cc..7d32448b79d0 100644 --- a/gfx/2d/PathRecording.h +++ b/gfx/2d/PathRecording.h @@ -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 Finish() override; @@ -73,8 +87,10 @@ class PathRecording : public Path { public: MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathRecording, override) - PathRecording(Path* aPath, const std::vector aOps, FillRule aFillRule) - : mPath(aPath), mPathOps(aOps), mFillRule(aFillRule) {} + PathRecording(Path* aPath, const std::vector 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 mPath; std::vector mPathOps; FillRule mFillRule; + Point mCurrentPoint; + Point mBeginPoint; // Event recorders that have this path in their event stream. std::vector> mStoredRecorders; diff --git a/gfx/2d/PathSkia.cpp b/gfx/2d/PathSkia.cpp index 97328602f29a..638e4e73b497 100644 --- a/gfx/2d/PathSkia.cpp +++ b/gfx/2d/PathSkia.cpp @@ -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 PathBuilderSkia::Finish() { + RefPtr path = MakeAndAddRef(mPath, mFillRule, + mCurrentPoint, mBeginPoint); mCurrentPoint = Point(0.0, 0.0); - mFirstPoint = Point(0.0, 0.0); - return MakeAndAddRef(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 PathSkia::CopyToBuilder( already_AddRefed PathSkia::TransformedCopyToBuilder( const Matrix& aTransform, FillRule aFillRule) const { - return MakeAndAddRef(aTransform, mPath, aFillRule); + RefPtr builder = MakeAndAddRef( + 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, diff --git a/gfx/2d/PathSkia.h b/gfx/2d/PathSkia.h index 280ca44f7898..95f152b07030 100644 --- a/gfx/2d/PathSkia.h +++ b/gfx/2d/PathSkia.h @@ -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 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 diff --git a/widget/gtk/nsNativeThemeGTK.cpp b/widget/gtk/nsNativeThemeGTK.cpp index 0626e2a58565..b55d662b5f39 100644 --- a/widget/gtk/nsNativeThemeGTK.cpp +++ b/widget/gtk/nsNativeThemeGTK.cpp @@ -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; };