add more conservative check for wayward divide

When the parallel stroke to the curve can't be computed from
the intersection of the tangent lines, as straight line connects
the two points instead. Allow the intersection to succeed unless
the ratio isn't finite or the contribution of (1 - ratio) isn't
significant.

R=reed@google.com,fmalita@chromium.org
BUG=skia:4603

Review URL: https://codereview.chromium.org/1484873003
This commit is contained in:
caryclark 2015-11-30 13:47:11 -08:00 committed by Commit bot
parent 69cfe95b7b
commit b775e91e87
2 changed files with 20 additions and 6 deletions

View File

@ -193,6 +193,22 @@ private:
typedef skiagm::GM INHERITED;
};
DEF_SIMPLE_GM(CubicStroke, canvas, 384, 384) {
SkPaint p;
p.setAntiAlias(true);
p.setStyle(SkPaint::kStroke_Style);
p.setStrokeWidth(1.0720f);
SkPath path;
path.moveTo(-6000,-6000);
path.cubicTo(-3500,5500,-500,5500,2500,-6500);
canvas->drawPath(path, p);
p.setStrokeWidth(1.0721f);
canvas->translate(10, 10);
canvas->drawPath(path, p);
p.setStrokeWidth(1.0722f);
canvas->translate(10, 10);
canvas->drawPath(path, p);
}
class Strokes2GM : public skiagm::GM {
SkPath fPath;

View File

@ -836,14 +836,12 @@ SkPathStroker::ResultType SkPathStroker::intersectRay(SkQuadConstruct* quadPts,
return STROKER_RESULT(kSplit_ResultType, depth, quadPts,
"(numerA=%g >= 0) == (numerB=%g >= 0)", numerA, numerB);
}
// check to see if the denomerator is teeny relative to the numerator
bool validDivide = SkScalarAbs(numerA) * SK_ScalarNearlyZero < SkScalarAbs(denom);
// the divide check is the same as checking if the scaled denom is nearly zero
// (commented out because on some platforms the two are not bit-identical)
// SkASSERT(!SkScalarNearlyZero(denom / numerA) == validDivide);
// check to see if the denominator is teeny relative to the numerator
// if the offset by one will be lost, the ratio is too large
numerA /= denom;
bool validDivide = numerA > numerA - 1;
if (validDivide) {
if (kCtrlPt_RayType == intersectRayType) {
numerA /= denom;
SkPoint* ctrlPt = &quadPts->fQuad[1];
// the intersection of the tangents need not be on the tangent segment
// so 0 <= numerA <= 1 is not necessarily true