Fix SkRRect::ConservativeIntersect when inputs share corner
Encountered while debugging new GrClipStack. Basically, with the old checks, if aCorner == bCorner but A was a rect, we'd end up rejecting it as not a viable intersection (failing the testCorner == aCorner checks), but wouldn't fall through to the testCorner == bCorner checks. Instead of splitting the if-elseif-else into separate ifs, I chose to add an additional if case that lets the ellipse containment check match a few more cases when we know the two ellipses share an anchor point. Change-Id: I6c8bc9a30d19a56f25da7d9be7832ff72dde1765 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315636 Reviewed-by: Jim Van Verth <jvanverth@google.com> Commit-Queue: Michael Ludwig <michaelludwig@google.com>
This commit is contained in:
parent
9bfe92a39d
commit
04b9443274
@ -790,7 +790,22 @@ SkRRect SkRRectPriv::ConservativeIntersect(const SkRRect& a, const SkRRect& b) {
|
|||||||
SkPoint aCorner = getCorner(a.rect(), corner);
|
SkPoint aCorner = getCorner(a.rect(), corner);
|
||||||
SkPoint bCorner = getCorner(b.rect(), corner);
|
SkPoint bCorner = getCorner(b.rect(), corner);
|
||||||
|
|
||||||
if (test == aCorner) {
|
if (test == aCorner && test == bCorner) {
|
||||||
|
// The round rects share a corner anchor, so pick A or B such that its X and Y radii
|
||||||
|
// are both larger than the other rrect's, or return false if neither A or B has the max
|
||||||
|
// corner radii (this is more permissive than the single corner tests below).
|
||||||
|
SkVector aRadii = a.radii(corner);
|
||||||
|
SkVector bRadii = b.radii(corner);
|
||||||
|
if (aRadii.fX >= bRadii.fX && aRadii.fY >= bRadii.fY) {
|
||||||
|
*radii = aRadii;
|
||||||
|
return true;
|
||||||
|
} else if (bRadii.fX >= aRadii.fX && bRadii.fY >= aRadii.fY) {
|
||||||
|
*radii = bRadii;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (test == aCorner) {
|
||||||
// Test that A's ellipse is contained by B. This is a non-trivial function to evaluate
|
// Test that A's ellipse is contained by B. This is a non-trivial function to evaluate
|
||||||
// so we resrict it to when the corners have the same radii. If not, we use the more
|
// so we resrict it to when the corners have the same radii. If not, we use the more
|
||||||
// conservative test that the extreme point of A's bounding box is contained in B.
|
// conservative test that the extreme point of A's bounding box is contained in B.
|
||||||
|
@ -1207,6 +1207,22 @@ static void test_conservative_intersection(skiatest::Reporter* reporter) {
|
|||||||
verify_success(reporter, a, make_inset(a, 1.f, 1.f), kB, kB, kB, kB);
|
verify_success(reporter, a, make_inset(a, 1.f, 1.f), kB, kB, kB, kB);
|
||||||
verify_success(reporter, make_inset(b, 2.f, 2.f), b, kA, kA, kA, kA);
|
verify_success(reporter, make_inset(b, 2.f, 2.f), b, kA, kA, kA, kA);
|
||||||
|
|
||||||
|
// A rectangle exactly matching the corners of the rrect bounds keeps the rrect radii,
|
||||||
|
// regardless of whether or not it's the 1st or 2nd arg to ConservativeIntersect.
|
||||||
|
SkRRect c = SkRRect::MakeRectXY({0.f, 0.f, 10.f, 10.f}, 2.f, 2.f);
|
||||||
|
SkRRect cT = SkRRect::MakeRect({0.f, 0.f, 10.f, 5.f});
|
||||||
|
verify_success(reporter, c, cT, kA, kA, kRect, kRect);
|
||||||
|
verify_success(reporter, cT, c, kB, kB, kRect, kRect);
|
||||||
|
SkRRect cB = SkRRect::MakeRect({0.f, 5.f, 10.f, 10.});
|
||||||
|
verify_success(reporter, c, cB, kRect, kRect, kA, kA);
|
||||||
|
verify_success(reporter, cB, c, kRect, kRect, kB, kB);
|
||||||
|
SkRRect cL = SkRRect::MakeRect({0.f, 0.f, 5.f, 10.f});
|
||||||
|
verify_success(reporter, c, cL, kA, kRect, kRect, kA);
|
||||||
|
verify_success(reporter, cL, c, kB, kRect, kRect, kB);
|
||||||
|
SkRRect cR = SkRRect::MakeRect({5.f, 0.f, 10.f, 10.f});
|
||||||
|
verify_success(reporter, c, cR, kRect, kA, kA, kRect);
|
||||||
|
verify_success(reporter, cR, c, kRect, kB, kB, kRect);
|
||||||
|
|
||||||
// Failed intersection operations:
|
// Failed intersection operations:
|
||||||
|
|
||||||
// A and B's bounds do not intersect
|
// A and B's bounds do not intersect
|
||||||
|
Loading…
Reference in New Issue
Block a user