зеркало из https://github.com/mozilla/gecko-dev.git
Bug 691187 - Prune zero-length segments for canvas strokes. r=lsalzman
Differential Revision: https://phabricator.services.mozilla.com/D179462
This commit is contained in:
Родитель
19abba01c7
Коммит
9975cde84f
|
@ -2955,7 +2955,7 @@ void CanvasRenderingContext2D::BeginPath() {
|
|||
void CanvasRenderingContext2D::Fill(const CanvasWindingRule& aWinding) {
|
||||
EnsureUserSpacePath(aWinding);
|
||||
|
||||
if (!mPath) {
|
||||
if (!mPath || mPath->IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -3022,7 +3022,7 @@ void CanvasRenderingContext2D::Fill(const CanvasPath& aPath,
|
|||
void CanvasRenderingContext2D::Stroke() {
|
||||
EnsureUserSpacePath();
|
||||
|
||||
if (!mPath) {
|
||||
if (!mPath || mPath->IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
mPathBuilder->MoveTo(pos);
|
||||
}
|
||||
|
||||
void CanvasPath::LineTo(double aX, double aY) {
|
||||
EnsurePathBuilder();
|
||||
|
||||
mPathBuilder->LineTo(Point(ToFloat(aX), ToFloat(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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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() {
|
||||
|
@ -248,6 +251,7 @@ void PathBuilderD2D::Arc(const Point& aOrigin, Float aRadius, Float aStartAngle,
|
|||
}
|
||||
|
||||
mCurrentPoint = endPoint;
|
||||
mFigureEmpty = false;
|
||||
}
|
||||
|
||||
void PathBuilderD2D::EnsureActive(const Point& aPoint) {
|
||||
|
@ -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 {
|
||||
|
|
|
@ -56,6 +56,7 @@ class PathBuilderD2D : public PathBuilder {
|
|||
RefPtr<ID2D1PathGeometry> mGeometry;
|
||||
|
||||
bool mFigureActive;
|
||||
bool mFigureEmpty = true;
|
||||
FillRule mFillRule;
|
||||
BackendType mBackendType;
|
||||
};
|
||||
|
@ -63,10 +64,11 @@ class PathBuilderD2D : public PathBuilder {
|
|||
class PathD2D : public Path {
|
||||
public:
|
||||
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(PathD2D, override)
|
||||
PathD2D(ID2D1PathGeometry* aGeometry, bool aEndedActive,
|
||||
PathD2D(ID2D1PathGeometry* aGeometry, bool aEndedActive, bool aIsEmpty,
|
||||
const Point& aEndPoint, FillRule aFillRule, BackendType aBackendType)
|
||||
: mGeometry(aGeometry),
|
||||
mEndedActive(aEndedActive),
|
||||
mIsEmpty(aIsEmpty),
|
||||
mEndPoint(aEndPoint),
|
||||
mFillRule(aFillRule),
|
||||
mBackendType(aBackendType) {}
|
||||
|
@ -93,6 +95,8 @@ class PathD2D : public Path {
|
|||
|
||||
virtual FillRule GetFillRule() const { return mFillRule; }
|
||||
|
||||
bool IsEmpty() const override { return mIsEmpty; }
|
||||
|
||||
ID2D1Geometry* GetGeometry() { return mGeometry; }
|
||||
|
||||
private:
|
||||
|
@ -101,6 +105,7 @@ class PathD2D : public Path {
|
|||
|
||||
mutable RefPtr<ID2D1PathGeometry> mGeometry;
|
||||
bool mEndedActive;
|
||||
bool mIsEmpty;
|
||||
Point mEndPoint;
|
||||
FillRule mFillRule;
|
||||
BackendType mBackendType;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "PathSkia.h"
|
||||
#include "HelpersSkia.h"
|
||||
#include "PathHelpers.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "skia/include/core/SkPathUtils.h"
|
||||
#include "skia/src/core/SkGeometry.h"
|
||||
|
||||
|
@ -270,4 +271,11 @@ Maybe<Rect> PathSkia::AsRect() const {
|
|||
}
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
bool PathSkia::IsEmpty() const {
|
||||
// Move/Close/Done segments are not included in the mask so as long as any
|
||||
// flag is set, we know that the path is non-empty.
|
||||
return mPath.getSegmentMasks() != 0;
|
||||
}
|
||||
|
||||
} // namespace mozilla::gfx
|
||||
|
|
|
@ -95,6 +95,8 @@ class PathSkia : public Path {
|
|||
const Matrix& aTransform, SkPath& aFillPath,
|
||||
const Maybe<Rect>& aClipRect = Nothing()) const;
|
||||
|
||||
bool IsEmpty() const override;
|
||||
|
||||
private:
|
||||
friend class DrawTargetSkia;
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
[2d.path.stroke.prune.arc.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Zero-length line segments from arcTo and arc are removed before stroking]
|
||||
expected: FAIL
|
|
@ -1,5 +0,0 @@
|
|||
[2d.path.stroke.prune.closed.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Zero-length line segments from closed paths are removed before stroking]
|
||||
expected: FAIL
|
|
@ -1,5 +0,0 @@
|
|||
[2d.path.stroke.prune.curve.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking]
|
||||
expected: FAIL
|
|
@ -1,5 +0,0 @@
|
|||
[2d.path.stroke.prune.line.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Zero-length line segments from lineTo are removed before stroking]
|
||||
expected: FAIL
|
|
@ -1,5 +0,0 @@
|
|||
[2d.path.stroke.prune.rect.html]
|
||||
expected:
|
||||
if (os == "android") and fission: [OK, TIMEOUT]
|
||||
[Zero-length line segments from rect and strokeRect are removed before stroking]
|
||||
expected: FAIL
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.arc.html]
|
||||
[Zero-length line segments from arcTo and arc are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.arc.worker.html]
|
||||
[Zero-length line segments from arcTo and arc are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.closed.html]
|
||||
[Zero-length line segments from closed paths are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.closed.worker.html]
|
||||
[Zero-length line segments from closed paths are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.curve.html]
|
||||
[Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.curve.worker.html]
|
||||
[Zero-length line segments from quadraticCurveTo and bezierCurveTo are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.line.html]
|
||||
[Zero-length line segments from lineTo are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.line.worker.html]
|
||||
[Zero-length line segments from lineTo are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.rect.html]
|
||||
[Zero-length line segments from rect and strokeRect are removed before stroking]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[2d.path.stroke.prune.rect.worker.html]
|
||||
[Zero-length line segments from rect and strokeRect are removed before stroking]
|
||||
expected: FAIL
|
||||
|
Загрузка…
Ссылка в новой задаче