Loading dom/canvas/CanvasRenderingContext2D.cpp +61 −14 Original line number Diff line number Diff line Loading @@ -2955,7 +2955,7 @@ void CanvasRenderingContext2D::BeginPath() { void CanvasRenderingContext2D::Fill(const CanvasWindingRule& aWinding) { EnsureUserSpacePath(aWinding); if (!mPath) { if (!mPath || mPath->IsEmpty()) { return; } Loading Loading @@ -2991,7 +2991,7 @@ void CanvasRenderingContext2D::Fill(const CanvasPath& aPath, } RefPtr<gfx::Path> gfxpath = aPath.GetPath(aWinding, mTarget); if (!gfxpath) { if (!gfxpath || gfxpath->IsEmpty()) { return; } Loading Loading @@ -3022,7 +3022,7 @@ void CanvasRenderingContext2D::Fill(const CanvasPath& aPath, void CanvasRenderingContext2D::Stroke() { EnsureUserSpacePath(); if (!mPath) { if (!mPath || mPath->IsEmpty()) { return; } Loading Loading @@ -3065,7 +3065,7 @@ void CanvasRenderingContext2D::Stroke(const CanvasPath& aPath) { RefPtr<gfx::Path> gfxpath = aPath.GetPath(CanvasWindingRule::Nonzero, mTarget); if (!gfxpath) { if (!gfxpath || gfxpath->IsEmpty()) { return; } Loading Loading @@ -3219,6 +3219,10 @@ void CanvasRenderingContext2D::ArcTo(double aX1, double aY1, double aX2, Point p1(aX1, aY1); Point p2(aX2, aY2); if (!p1.IsFinite() || !p2.IsFinite() || !std::isfinite(aRadius)) { return; } // Execute these calculations in double precision to avoid cumulative // rounding errors. double dir, a2, b2, c2, cosx, sinx, d, anx, any, bnx, bny, x3, y3, x4, y4, cx, Loading @@ -3226,7 +3230,7 @@ void CanvasRenderingContext2D::ArcTo(double aX1, double aY1, double aX2, bool anticlockwise; if (p0 == p1 || p1 == p2 || aRadius == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading @@ -3234,7 +3238,7 @@ void CanvasRenderingContext2D::ArcTo(double aX1, double aY1, double aX2, dir = (p2.x.value - p1.x.value) * (p0.y.value - p1.y.value) + (p2.y.value - p1.y.value) * (p1.x.value - p0.x.value); if (dir == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading Loading @@ -3285,8 +3289,16 @@ void CanvasRenderingContext2D::Rect(double aX, double aY, double aW, double aH) { EnsureWritablePath(); if (!std::isfinite(aX) || !std::isfinite(aY) || !std::isfinite(aW) || !std::isfinite(aH)) { return; } if (mPathBuilder) { mPathBuilder->MoveTo(Point(aX, aY)); if (aW == 0 && aH == 0) { return; } mPathBuilder->LineTo(Point(aX + aW, aY)); mPathBuilder->LineTo(Point(aX + aW, aY + aH)); mPathBuilder->LineTo(Point(aX, aY + aH)); Loading @@ -3294,6 +3306,9 @@ void CanvasRenderingContext2D::Rect(double aX, double aY, double aW, } else { mDSPathBuilder->MoveTo( mTarget->GetTransform().TransformPoint(Point(aX, aY))); if (aW == 0 && aH == 0) { return; } mDSPathBuilder->LineTo( mTarget->GetTransform().TransformPoint(Point(aX + aW, aY))); mDSPathBuilder->LineTo( Loading Loading @@ -6310,21 +6325,30 @@ void CanvasPath::ClosePath() { void CanvasPath::MoveTo(double aX, double aY) { EnsurePathBuilder(); mPathBuilder->MoveTo(Point(ToFloat(aX), ToFloat(aY))); Point pos(ToFloat(aX), ToFloat(aY)); if (!pos.IsFinite()) { return; } void CanvasPath::LineTo(double aX, double aY) { EnsurePathBuilder(); mPathBuilder->MoveTo(pos); } mPathBuilder->LineTo(Point(ToFloat(aX), ToFloat(aY))); void CanvasPath::LineTo(double aX, double aY) { LineTo(Point(ToFloat(aX), ToFloat(aY))); } void CanvasPath::QuadraticCurveTo(double aCpx, double aCpy, double aX, double aY) { EnsurePathBuilder(); mPathBuilder->QuadraticBezierTo(gfx::Point(ToFloat(aCpx), ToFloat(aCpy)), gfx::Point(ToFloat(aX), ToFloat(aY))); Point cp1(ToFloat(aCpx), ToFloat(aCpy)); Point cp2(ToFloat(aX), ToFloat(aY)); if (!cp1.IsFinite() || !cp2.IsFinite() || (cp1 == mPathBuilder->CurrentPoint() && cp1 == cp2)) { return; } mPathBuilder->QuadraticBezierTo(cp1, cp2); } void CanvasPath::BezierCurveTo(double aCp1x, double aCp1y, double aCp2x, Loading @@ -6347,6 +6371,10 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, Point p1(aX1, aY1); Point p2(aX2, aY2); if (!p1.IsFinite() || !p2.IsFinite() || !std::isfinite(aRadius)) { return; } // Execute these calculations in double precision to avoid cumulative // rounding errors. double dir, a2, b2, c2, cosx, sinx, d, anx, any, bnx, bny, x3, y3, x4, y4, cx, Loading @@ -6354,7 +6382,7 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, bool anticlockwise; if (p0 == p1 || p1 == p2 || aRadius == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading @@ -6362,7 +6390,7 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, dir = (p2.x.value - p1.x.value) * (p0.y.value - p1.y.value) + (p2.y.value - p1.y.value) * (p1.x.value - p0.x.value); if (dir == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading Loading @@ -6397,7 +6425,17 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, } void CanvasPath::Rect(double aX, double aY, double aW, double aH) { EnsurePathBuilder(); if (!std::isfinite(aX) || !std::isfinite(aY) || !std::isfinite(aW) || !std::isfinite(aH)) { return; } MoveTo(aX, aY); if (aW == 0 && aH == 0) { return; } LineTo(aX + aW, aY); LineTo(aX + aW, aY + aH); LineTo(aX, aY + aH); Loading Loading @@ -6443,6 +6481,10 @@ void CanvasPath::Ellipse(double x, double y, double radiusX, double radiusY, void CanvasPath::LineTo(const gfx::Point& aPoint) { EnsurePathBuilder(); if (!aPoint.IsFinite() || aPoint == mPathBuilder->CurrentPoint()) { return; } mPathBuilder->LineTo(aPoint); } Loading @@ -6450,6 +6492,11 @@ void CanvasPath::BezierTo(const gfx::Point& aCP1, const gfx::Point& aCP2, const gfx::Point& aCP3) { EnsurePathBuilder(); if (!aCP1.IsFinite() || !aCP2.IsFinite() || !aCP3.IsFinite() || (aCP1 == mPathBuilder->CurrentPoint() && aCP1 == aCP2 && aCP1 == aCP3)) { return; } mPathBuilder->BezierTo(aCP1, aCP2, aCP3); } Loading dom/canvas/CanvasRenderingContext2D.h +51 −14 Original line number Diff line number Diff line Loading @@ -337,11 +337,17 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, void MoveTo(double aX, double aY) override { EnsureWritablePath(); mozilla::gfx::Point pos(ToFloat(aX), ToFloat(aY)); if (!pos.IsFinite()) { return; } if (mPathBuilder) { mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); mPathBuilder->MoveTo(pos); } else { mDSPathBuilder->MoveTo(mTarget->GetTransform().TransformPoint( mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)))); mozilla::gfx::Point transformedPos = mTarget->GetTransform().TransformPoint(pos); mDSPathBuilder->MoveTo(transformedPos); } } Loading @@ -355,17 +361,25 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, double aY) override { EnsureWritablePath(); mozilla::gfx::Point cp1(ToFloat(aCpx), ToFloat(aCpy)); mozilla::gfx::Point cp2(ToFloat(aX), ToFloat(aY)); if (!cp1.IsFinite() || !cp2.IsFinite()) { return; } if (mPathBuilder) { mPathBuilder->QuadraticBezierTo( mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy)), mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); if (cp1 == mPathBuilder->CurrentPoint() && cp1 == cp2) { return; } mPathBuilder->QuadraticBezierTo(cp1, cp2); } else { mozilla::gfx::Matrix transform = mTarget->GetTransform(); mDSPathBuilder->QuadraticBezierTo( transform.TransformPoint( mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy))), transform.TransformPoint( mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)))); mozilla::gfx::Point transformedPos = transform.TransformPoint(cp1); if (transformedPos == mDSPathBuilder->CurrentPoint() && cp1 == cp2) { return; } mDSPathBuilder->QuadraticBezierTo(transformedPos, transform.TransformPoint(cp2)); } } Loading Loading @@ -501,22 +515,45 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, enum class Style : uint8_t { STROKE = 0, FILL, MAX }; void LineTo(const mozilla::gfx::Point& aPoint) { if (!aPoint.IsFinite()) { return; } if (mPathBuilder) { if (mPathBuilder->CurrentPoint() == aPoint) { return; } mPathBuilder->LineTo(aPoint); } else { mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(aPoint)); mozilla::gfx::Point transformedPt = mTarget->GetTransform().TransformPoint(aPoint); if (mDSPathBuilder->CurrentPoint() == transformedPt) { return; } mDSPathBuilder->LineTo(transformedPt); } } void BezierTo(const mozilla::gfx::Point& aCP1, const mozilla::gfx::Point& aCP2, const mozilla::gfx::Point& aCP3) { if (!aCP1.IsFinite() || !aCP2.IsFinite() || !aCP3.IsFinite()) { return; } if (mPathBuilder) { if (aCP1 == mPathBuilder->CurrentPoint() && aCP1 == aCP2 && aCP1 == aCP3) { return; } mPathBuilder->BezierTo(aCP1, aCP2, aCP3); } else { mozilla::gfx::Matrix transform = mTarget->GetTransform(); mDSPathBuilder->BezierTo(transform.TransformPoint(aCP1), transform.TransformPoint(aCP2), mozilla::gfx::Point transformedPos = transform.TransformPoint(aCP1); if (transformedPos == mDSPathBuilder->CurrentPoint() && aCP1 == aCP2 && aCP1 == aCP3) { return; } mDSPathBuilder->BezierTo(transformedPos, transform.TransformPoint(aCP2), transform.TransformPoint(aCP3)); } } Loading dom/canvas/test/test_canvas.html +4 −4 Original line number Diff line number Diff line Loading @@ -14252,7 +14252,7 @@ ctx.lineTo(50, 25); ctx.closePath(); ctx.stroke(); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading Loading @@ -14324,7 +14324,7 @@ ctx.moveTo(50, 25); ctx.bezierCurveTo(50, 25, 50, 25, 50, 25); ctx.stroke(); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading Loading @@ -14356,7 +14356,7 @@ ctx.moveTo(50, 25); ctx.lineTo(50, 25); ctx.stroke(); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading Loading @@ -14389,7 +14389,7 @@ ctx.stroke(); ctx.strokeRect(50, 25, 0, 0); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading gfx/2d/2D.h +2 −0 Original line number Diff line number Diff line Loading @@ -1007,6 +1007,8 @@ class Path : public external::AtomicRefCounted<Path> { virtual Point ComputePointAtLength(Float aLength, Point* aTangent = nullptr); virtual bool IsEmpty() const { return false; } protected: Path(); void EnsureFlattenedPath(); Loading gfx/2d/PathD2D.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ void PathBuilderD2D::LineTo(const Point& aPoint) { mSink->AddLine(D2DPoint(aPoint)); mCurrentPoint = aPoint; mFigureEmpty = false; } void PathBuilderD2D::BezierTo(const Point& aCP1, const Point& aCP2, Loading @@ -143,6 +144,7 @@ void PathBuilderD2D::BezierTo(const Point& aCP1, const Point& aCP2, D2D1::BezierSegment(D2DPoint(aCP1), D2DPoint(aCP2), D2DPoint(aCP3))); mCurrentPoint = aCP3; mFigureEmpty = false; } void PathBuilderD2D::QuadraticBezierTo(const Point& aCP1, const Point& aCP2) { Loading @@ -151,6 +153,7 @@ void PathBuilderD2D::QuadraticBezierTo(const Point& aCP1, const Point& aCP2) { D2D1::QuadraticBezierSegment(D2DPoint(aCP1), D2DPoint(aCP2))); mCurrentPoint = aCP2; mFigureEmpty = false; } void PathBuilderD2D::Close() { Loading Loading @@ -248,6 +251,7 @@ void PathBuilderD2D::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle, } mCurrentPoint = endPoint; mFigureEmpty = false; } void PathBuilderD2D::EnsureActive(const Point& aPoint) { Loading @@ -269,8 +273,8 @@ already_AddRefed<Path> PathBuilderD2D::Finish() { return nullptr; } return MakeAndAddRef<PathD2D>(mGeometry, mFigureActive, mCurrentPoint, mFillRule, mBackendType); return MakeAndAddRef<PathD2D>(mGeometry, mFigureActive, mFigureEmpty, mCurrentPoint, mFillRule, mBackendType); } already_AddRefed<PathBuilder> PathD2D::CopyToBuilder(FillRule aFillRule) const { Loading Loading
dom/canvas/CanvasRenderingContext2D.cpp +61 −14 Original line number Diff line number Diff line Loading @@ -2955,7 +2955,7 @@ void CanvasRenderingContext2D::BeginPath() { void CanvasRenderingContext2D::Fill(const CanvasWindingRule& aWinding) { EnsureUserSpacePath(aWinding); if (!mPath) { if (!mPath || mPath->IsEmpty()) { return; } Loading Loading @@ -2991,7 +2991,7 @@ void CanvasRenderingContext2D::Fill(const CanvasPath& aPath, } RefPtr<gfx::Path> gfxpath = aPath.GetPath(aWinding, mTarget); if (!gfxpath) { if (!gfxpath || gfxpath->IsEmpty()) { return; } Loading Loading @@ -3022,7 +3022,7 @@ void CanvasRenderingContext2D::Fill(const CanvasPath& aPath, void CanvasRenderingContext2D::Stroke() { EnsureUserSpacePath(); if (!mPath) { if (!mPath || mPath->IsEmpty()) { return; } Loading Loading @@ -3065,7 +3065,7 @@ void CanvasRenderingContext2D::Stroke(const CanvasPath& aPath) { RefPtr<gfx::Path> gfxpath = aPath.GetPath(CanvasWindingRule::Nonzero, mTarget); if (!gfxpath) { if (!gfxpath || gfxpath->IsEmpty()) { return; } Loading Loading @@ -3219,6 +3219,10 @@ void CanvasRenderingContext2D::ArcTo(double aX1, double aY1, double aX2, Point p1(aX1, aY1); Point p2(aX2, aY2); if (!p1.IsFinite() || !p2.IsFinite() || !std::isfinite(aRadius)) { return; } // Execute these calculations in double precision to avoid cumulative // rounding errors. double dir, a2, b2, c2, cosx, sinx, d, anx, any, bnx, bny, x3, y3, x4, y4, cx, Loading @@ -3226,7 +3230,7 @@ void CanvasRenderingContext2D::ArcTo(double aX1, double aY1, double aX2, bool anticlockwise; if (p0 == p1 || p1 == p2 || aRadius == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading @@ -3234,7 +3238,7 @@ void CanvasRenderingContext2D::ArcTo(double aX1, double aY1, double aX2, dir = (p2.x.value - p1.x.value) * (p0.y.value - p1.y.value) + (p2.y.value - p1.y.value) * (p1.x.value - p0.x.value); if (dir == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading Loading @@ -3285,8 +3289,16 @@ void CanvasRenderingContext2D::Rect(double aX, double aY, double aW, double aH) { EnsureWritablePath(); if (!std::isfinite(aX) || !std::isfinite(aY) || !std::isfinite(aW) || !std::isfinite(aH)) { return; } if (mPathBuilder) { mPathBuilder->MoveTo(Point(aX, aY)); if (aW == 0 && aH == 0) { return; } mPathBuilder->LineTo(Point(aX + aW, aY)); mPathBuilder->LineTo(Point(aX + aW, aY + aH)); mPathBuilder->LineTo(Point(aX, aY + aH)); Loading @@ -3294,6 +3306,9 @@ void CanvasRenderingContext2D::Rect(double aX, double aY, double aW, } else { mDSPathBuilder->MoveTo( mTarget->GetTransform().TransformPoint(Point(aX, aY))); if (aW == 0 && aH == 0) { return; } mDSPathBuilder->LineTo( mTarget->GetTransform().TransformPoint(Point(aX + aW, aY))); mDSPathBuilder->LineTo( Loading Loading @@ -6310,21 +6325,30 @@ void CanvasPath::ClosePath() { void CanvasPath::MoveTo(double aX, double aY) { EnsurePathBuilder(); mPathBuilder->MoveTo(Point(ToFloat(aX), ToFloat(aY))); Point pos(ToFloat(aX), ToFloat(aY)); if (!pos.IsFinite()) { return; } void CanvasPath::LineTo(double aX, double aY) { EnsurePathBuilder(); mPathBuilder->MoveTo(pos); } mPathBuilder->LineTo(Point(ToFloat(aX), ToFloat(aY))); void CanvasPath::LineTo(double aX, double aY) { LineTo(Point(ToFloat(aX), ToFloat(aY))); } void CanvasPath::QuadraticCurveTo(double aCpx, double aCpy, double aX, double aY) { EnsurePathBuilder(); mPathBuilder->QuadraticBezierTo(gfx::Point(ToFloat(aCpx), ToFloat(aCpy)), gfx::Point(ToFloat(aX), ToFloat(aY))); Point cp1(ToFloat(aCpx), ToFloat(aCpy)); Point cp2(ToFloat(aX), ToFloat(aY)); if (!cp1.IsFinite() || !cp2.IsFinite() || (cp1 == mPathBuilder->CurrentPoint() && cp1 == cp2)) { return; } mPathBuilder->QuadraticBezierTo(cp1, cp2); } void CanvasPath::BezierCurveTo(double aCp1x, double aCp1y, double aCp2x, Loading @@ -6347,6 +6371,10 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, Point p1(aX1, aY1); Point p2(aX2, aY2); if (!p1.IsFinite() || !p2.IsFinite() || !std::isfinite(aRadius)) { return; } // Execute these calculations in double precision to avoid cumulative // rounding errors. double dir, a2, b2, c2, cosx, sinx, d, anx, any, bnx, bny, x3, y3, x4, y4, cx, Loading @@ -6354,7 +6382,7 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, bool anticlockwise; if (p0 == p1 || p1 == p2 || aRadius == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading @@ -6362,7 +6390,7 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, dir = (p2.x.value - p1.x.value) * (p0.y.value - p1.y.value) + (p2.y.value - p1.y.value) * (p1.x.value - p0.x.value); if (dir == 0) { LineTo(p1.x, p1.y); LineTo(p1); return; } Loading Loading @@ -6397,7 +6425,17 @@ void CanvasPath::ArcTo(double aX1, double aY1, double aX2, double aY2, } void CanvasPath::Rect(double aX, double aY, double aW, double aH) { EnsurePathBuilder(); if (!std::isfinite(aX) || !std::isfinite(aY) || !std::isfinite(aW) || !std::isfinite(aH)) { return; } MoveTo(aX, aY); if (aW == 0 && aH == 0) { return; } LineTo(aX + aW, aY); LineTo(aX + aW, aY + aH); LineTo(aX, aY + aH); Loading Loading @@ -6443,6 +6481,10 @@ void CanvasPath::Ellipse(double x, double y, double radiusX, double radiusY, void CanvasPath::LineTo(const gfx::Point& aPoint) { EnsurePathBuilder(); if (!aPoint.IsFinite() || aPoint == mPathBuilder->CurrentPoint()) { return; } mPathBuilder->LineTo(aPoint); } Loading @@ -6450,6 +6492,11 @@ void CanvasPath::BezierTo(const gfx::Point& aCP1, const gfx::Point& aCP2, const gfx::Point& aCP3) { EnsurePathBuilder(); if (!aCP1.IsFinite() || !aCP2.IsFinite() || !aCP3.IsFinite() || (aCP1 == mPathBuilder->CurrentPoint() && aCP1 == aCP2 && aCP1 == aCP3)) { return; } mPathBuilder->BezierTo(aCP1, aCP2, aCP3); } Loading
dom/canvas/CanvasRenderingContext2D.h +51 −14 Original line number Diff line number Diff line Loading @@ -337,11 +337,17 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, void MoveTo(double aX, double aY) override { EnsureWritablePath(); mozilla::gfx::Point pos(ToFloat(aX), ToFloat(aY)); if (!pos.IsFinite()) { return; } if (mPathBuilder) { mPathBuilder->MoveTo(mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); mPathBuilder->MoveTo(pos); } else { mDSPathBuilder->MoveTo(mTarget->GetTransform().TransformPoint( mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)))); mozilla::gfx::Point transformedPos = mTarget->GetTransform().TransformPoint(pos); mDSPathBuilder->MoveTo(transformedPos); } } Loading @@ -355,17 +361,25 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, double aY) override { EnsureWritablePath(); mozilla::gfx::Point cp1(ToFloat(aCpx), ToFloat(aCpy)); mozilla::gfx::Point cp2(ToFloat(aX), ToFloat(aY)); if (!cp1.IsFinite() || !cp2.IsFinite()) { return; } if (mPathBuilder) { mPathBuilder->QuadraticBezierTo( mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy)), mozilla::gfx::Point(ToFloat(aX), ToFloat(aY))); if (cp1 == mPathBuilder->CurrentPoint() && cp1 == cp2) { return; } mPathBuilder->QuadraticBezierTo(cp1, cp2); } else { mozilla::gfx::Matrix transform = mTarget->GetTransform(); mDSPathBuilder->QuadraticBezierTo( transform.TransformPoint( mozilla::gfx::Point(ToFloat(aCpx), ToFloat(aCpy))), transform.TransformPoint( mozilla::gfx::Point(ToFloat(aX), ToFloat(aY)))); mozilla::gfx::Point transformedPos = transform.TransformPoint(cp1); if (transformedPos == mDSPathBuilder->CurrentPoint() && cp1 == cp2) { return; } mDSPathBuilder->QuadraticBezierTo(transformedPos, transform.TransformPoint(cp2)); } } Loading Loading @@ -501,22 +515,45 @@ class CanvasRenderingContext2D : public nsICanvasRenderingContextInternal, enum class Style : uint8_t { STROKE = 0, FILL, MAX }; void LineTo(const mozilla::gfx::Point& aPoint) { if (!aPoint.IsFinite()) { return; } if (mPathBuilder) { if (mPathBuilder->CurrentPoint() == aPoint) { return; } mPathBuilder->LineTo(aPoint); } else { mDSPathBuilder->LineTo(mTarget->GetTransform().TransformPoint(aPoint)); mozilla::gfx::Point transformedPt = mTarget->GetTransform().TransformPoint(aPoint); if (mDSPathBuilder->CurrentPoint() == transformedPt) { return; } mDSPathBuilder->LineTo(transformedPt); } } void BezierTo(const mozilla::gfx::Point& aCP1, const mozilla::gfx::Point& aCP2, const mozilla::gfx::Point& aCP3) { if (!aCP1.IsFinite() || !aCP2.IsFinite() || !aCP3.IsFinite()) { return; } if (mPathBuilder) { if (aCP1 == mPathBuilder->CurrentPoint() && aCP1 == aCP2 && aCP1 == aCP3) { return; } mPathBuilder->BezierTo(aCP1, aCP2, aCP3); } else { mozilla::gfx::Matrix transform = mTarget->GetTransform(); mDSPathBuilder->BezierTo(transform.TransformPoint(aCP1), transform.TransformPoint(aCP2), mozilla::gfx::Point transformedPos = transform.TransformPoint(aCP1); if (transformedPos == mDSPathBuilder->CurrentPoint() && aCP1 == aCP2 && aCP1 == aCP3) { return; } mDSPathBuilder->BezierTo(transformedPos, transform.TransformPoint(aCP2), transform.TransformPoint(aCP3)); } } Loading
dom/canvas/test/test_canvas.html +4 −4 Original line number Diff line number Diff line Loading @@ -14252,7 +14252,7 @@ ctx.lineTo(50, 25); ctx.closePath(); ctx.stroke(); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading Loading @@ -14324,7 +14324,7 @@ ctx.moveTo(50, 25); ctx.bezierCurveTo(50, 25, 50, 25, 50, 25); ctx.stroke(); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading Loading @@ -14356,7 +14356,7 @@ ctx.moveTo(50, 25); ctx.lineTo(50, 25); ctx.stroke(); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading Loading @@ -14389,7 +14389,7 @@ ctx.stroke(); ctx.strokeRect(50, 25, 0, 0); todo_isPixel(ctx, 50,25, 0,255,0,255, 0); isPixel(ctx, 50,25, 0,255,0,255, 0); } </script> Loading
gfx/2d/2D.h +2 −0 Original line number Diff line number Diff line Loading @@ -1007,6 +1007,8 @@ class Path : public external::AtomicRefCounted<Path> { virtual Point ComputePointAtLength(Float aLength, Point* aTangent = nullptr); virtual bool IsEmpty() const { return false; } protected: Path(); void EnsureFlattenedPath(); Loading
gfx/2d/PathD2D.cpp +6 −2 Original line number Diff line number Diff line Loading @@ -134,6 +134,7 @@ void PathBuilderD2D::LineTo(const Point& aPoint) { mSink->AddLine(D2DPoint(aPoint)); mCurrentPoint = aPoint; mFigureEmpty = false; } void PathBuilderD2D::BezierTo(const Point& aCP1, const Point& aCP2, Loading @@ -143,6 +144,7 @@ void PathBuilderD2D::BezierTo(const Point& aCP1, const Point& aCP2, D2D1::BezierSegment(D2DPoint(aCP1), D2DPoint(aCP2), D2DPoint(aCP3))); mCurrentPoint = aCP3; mFigureEmpty = false; } void PathBuilderD2D::QuadraticBezierTo(const Point& aCP1, const Point& aCP2) { Loading @@ -151,6 +153,7 @@ void PathBuilderD2D::QuadraticBezierTo(const Point& aCP1, const Point& aCP2) { D2D1::QuadraticBezierSegment(D2DPoint(aCP1), D2DPoint(aCP2))); mCurrentPoint = aCP2; mFigureEmpty = false; } void PathBuilderD2D::Close() { Loading Loading @@ -248,6 +251,7 @@ void PathBuilderD2D::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle, } mCurrentPoint = endPoint; mFigureEmpty = false; } void PathBuilderD2D::EnsureActive(const Point& aPoint) { Loading @@ -269,8 +273,8 @@ already_AddRefed<Path> PathBuilderD2D::Finish() { return nullptr; } return MakeAndAddRef<PathD2D>(mGeometry, mFigureActive, mCurrentPoint, mFillRule, mBackendType); return MakeAndAddRef<PathD2D>(mGeometry, mFigureActive, mFigureEmpty, mCurrentPoint, mFillRule, mBackendType); } already_AddRefed<PathBuilder> PathD2D::CopyToBuilder(FillRule aFillRule) const { Loading