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->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 {
@ -104,10 +118,13 @@ protected:
canvas->translate(0, 110);
}
canvas->restore();
this->drawGiantCircle(canvas);
}
private:
SkTArray<SkPath> fPaths;
SkPath fGiantCircle;
typedef skiagm::GM INHERITED;
};
DEF_GM( return SkNEW(ConicPathsGM); )

View File

@ -223,7 +223,9 @@ SkScalar SkPoint::distanceToLineBetweenSqd(const SkPoint& a,
1 == kRight_Side);
*side = (Side) SkScalarSignAsInt(det);
}
return SkScalarMulDiv(det, det, uLengthSqd);
SkScalar temp = det / uLengthSqd;
temp *= det;
return temp;
}
SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
@ -256,6 +258,8 @@ SkScalar SkPoint::distanceToLineSegmentBetweenSqd(const SkPoint& a,
return b.distanceToSqd(*this);
} else {
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)
// points.
// 2^(log4(x)) = sqrt(x);
int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol)));
int pow2 = GrNextPow2(temp);
// 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;
SkScalar divSqrt = SkScalarSqrt(SkScalarDiv(d, tol));
if (((SkScalar)SK_MaxS32) <= divSqrt) {
return MAX_POINTS_PER_CURVE;
} else {
int temp = SkScalarCeilToInt(divSqrt);
int pow2 = GrNextPow2(temp);
// 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) {
return 1;
} else {
int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol)));
int pow2 = GrNextPow2(temp);
// 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;
SkScalar divSqrt = SkScalarSqrt(SkScalarDiv(d, tol));
if (((SkScalar)SK_MaxS32) <= divSqrt) {
return MAX_POINTS_PER_CURVE;
} else {
int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol)));
int pow2 = GrNextPow2(temp);
// 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);
}
}