зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
5e669cb7bb
Коммит
c44ff5af9a
23
gfx/2d/2D.h
23
gfx/2d/2D.h
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче