harden line clipper against slight numerical drift.

Bug: skia:7491
Change-Id: I8d2b7cbfb580c0aabc76a72dfb317c35db43b329
Reviewed-on: https://skia-review.googlesource.com/113425
Reviewed-by: Cary Clark <caryclark@google.com>
Commit-Queue: Mike Reed <reed@google.com>
This commit is contained in:
Mike Reed 2018-03-09 14:10:08 -05:00 committed by Skia Commit-Bot
parent 5a0cba9826
commit d2c663768c

View File

@ -60,6 +60,15 @@ static SkScalar sect_with_vertical(const SkPoint src[2], SkScalar X) {
}
}
static SkScalar sect_clamp_with_vertical(const SkPoint src[2], SkScalar x) {
SkScalar y = sect_with_vertical(src, x);
// Our caller expects y to be between src[0].fY and src[1].fY (unsorted), but due to the
// numerics of floats/doubles, we might have computed a value slightly outside of that,
// so we have to manually clamp afterwards.
// See skbug.com/7491
return pin_unsorted(y, src[0].fY, src[1].fY);
}
///////////////////////////////////////////////////////////////////////////////
static inline bool nestedLT(SkScalar a, SkScalar b, SkScalar dim) {
@ -229,7 +238,7 @@ int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip, SkPoint lin
if (tmp[index0].fX < clip.fLeft) {
r->set(clip.fLeft, tmp[index0].fY);
r += 1;
r->set(clip.fLeft, sect_with_vertical(tmp, clip.fLeft));
r->set(clip.fLeft, sect_clamp_with_vertical(tmp, clip.fLeft));
SkASSERT(is_between_unsorted(r->fY, tmp[0].fY, tmp[1].fY));
} else {
*r = tmp[index0];
@ -237,7 +246,7 @@ int SkLineClipper::ClipLine(const SkPoint pts[], const SkRect& clip, SkPoint lin
r += 1;
if (tmp[index1].fX > clip.fRight) {
r->set(clip.fRight, sect_with_vertical(tmp, clip.fRight));
r->set(clip.fRight, sect_clamp_with_vertical(tmp, clip.fRight));
SkASSERT(is_between_unsorted(r->fY, tmp[0].fY, tmp[1].fY));
r += 1;
r->set(clip.fRight, tmp[index1].fY);