Fix to check for inf when generating quadratic points

BUG=skia:3453

Review URL: https://codereview.chromium.org/948043003
This commit is contained in:
egdaniel 2015-02-25 06:41:47 -08:00 committed by Commit bot
parent 86821b5670
commit 5a23a14b1f
3 changed files with 49 additions and 18 deletions

View File

@ -72,6 +72,20 @@ protected:
closedEllipse->moveTo(0, 0); closedEllipse->moveTo(0, 0);
closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf); closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf);
} }
{
const SkScalar w = SkScalarSqrt(2)/2;
fGiantCircle.moveTo(2.1e+11f, -1.05e+11f);
fGiantCircle.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w);
fGiantCircle.conicTo(0, 0, 0, -1.05e+11f, w);
fGiantCircle.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w);
fGiantCircle.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w);
}
}
void drawGiantCircle(SkCanvas* canvas) {
SkPaint paint;
canvas->drawPath(fGiantCircle, paint);
} }
void onDraw(SkCanvas* canvas) SK_OVERRIDE { void onDraw(SkCanvas* canvas) SK_OVERRIDE {
@ -104,10 +118,13 @@ protected:
canvas->translate(0, 110); canvas->translate(0, 110);
} }
canvas->restore(); canvas->restore();
this->drawGiantCircle(canvas);
} }
private: private:
SkTArray<SkPath> fPaths; SkTArray<SkPath> fPaths;
SkPath fGiantCircle;
typedef skiagm::GM INHERITED; typedef skiagm::GM INHERITED;
}; };
DEF_GM( return SkNEW(ConicPathsGM); ) DEF_GM( return SkNEW(ConicPathsGM); )

View File

@ -223,7 +223,9 @@ SkScalar SkPoint::distanceToLineBetweenSqd(const SkPoint& a,
1 == kRight_Side); 1 == kRight_Side);
*side = (Side) SkScalarSignAsInt(det); *side = (Side) SkScalarSignAsInt(det);
} }
return SkScalarMulDiv(det, det, uLengthSqd); SkScalar temp = det / uLengthSqd;
temp *= det;
return temp;
} }
SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a, SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
@ -256,6 +258,8 @@ SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
return b.distanceToSqd(*this); return b.distanceToSqd(*this);
} else { } else {
SkScalar det = u.cross(v); SkScalar det = u.cross(v);
return SkScalarMulDiv(det, det, uLengthSqd); SkScalar temp = det / uLengthSqd;
temp *= det;
return temp;
} }
} }

View File

@ -51,15 +51,20 @@ uint32_t GrPathUtils::quadraticPointCount(const SkPoint points[],
// subdivide x = log4(d/tol) times. x subdivisions creates 2^(x) // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x)
// points. // points.
// 2^(log4(x)) = sqrt(x); // 2^(log4(x)) = sqrt(x);
int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol))); SkScalar divSqrt = SkScalarSqrt(SkScalarDiv(d, tol));
int pow2 = GrNextPow2(temp); if (((SkScalar)SK_MaxS32) <= divSqrt) {
// Because of NaNs & INFs we can wind up with a degenerate temp return MAX_POINTS_PER_CURVE;
// such that pow2 comes out negative. Also, our point generator } else {
// will always output at least one pt. int temp = SkScalarCeilToInt(divSqrt);
if (pow2 < 1) { int pow2 = GrNextPow2(temp);
pow2 = 1; // Because of NaNs & INFs we can wind up with a degenerate temp
// such that pow2 comes out negative. Also, our point generator
// will always output at least one pt.
if (pow2 < 1) {
pow2 = 1;
}
return SkTMin(pow2, MAX_POINTS_PER_CURVE);
} }
return SkTMin(pow2, MAX_POINTS_PER_CURVE);
} }
} }
@ -102,15 +107,20 @@ uint32_t GrPathUtils::cubicPointCount(const SkPoint points[],
if (d <= tol) { if (d <= tol) {
return 1; return 1;
} else { } else {
int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol))); SkScalar divSqrt = SkScalarSqrt(SkScalarDiv(d, tol));
int pow2 = GrNextPow2(temp); if (((SkScalar)SK_MaxS32) <= divSqrt) {
// Because of NaNs & INFs we can wind up with a degenerate temp return MAX_POINTS_PER_CURVE;
// such that pow2 comes out negative. Also, our point generator } else {
// will always output at least one pt. int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol)));
if (pow2 < 1) { int pow2 = GrNextPow2(temp);
pow2 = 1; // Because of NaNs & INFs we can wind up with a degenerate temp
// such that pow2 comes out negative. Also, our point generator
// will always output at least one pt.
if (pow2 < 1) {
pow2 = 1;
}
return SkTMin(pow2, MAX_POINTS_PER_CURVE);
} }
return SkTMin(pow2, MAX_POINTS_PER_CURVE);
} }
} }