aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/SkRRect.cpp35
1 files changed, 32 insertions, 3 deletions
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index fc1a1cf057..c8d0329fe3 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -134,6 +134,12 @@ bool SkRRect::contains(SkScalar x, SkScalar y) const {
// We know the point is inside the RR's bounds. The only way it can
// be out is if it outside one of the corners
+ return checkCornerContainment(x, y);
+}
+
+// This method determines if a point known to be inside the RRect's bounds is
+// inside all the corners.
+bool SkRRect::checkCornerContainment(SkScalar x, SkScalar y) const {
SkPoint canonicalPt; // (x,y) translated to one of the quadrants
int index;
@@ -179,9 +185,32 @@ bool SkRRect::contains(SkScalar x, SkScalar y) const {
// x^2 y^2
// ----- + ----- <= 1
// a^2 b^2
- SkScalar dist = SkScalarDiv(SkScalarSquare(canonicalPt.fX), SkScalarSquare(fRadii[index].fX)) +
- SkScalarDiv(SkScalarSquare(canonicalPt.fY), SkScalarSquare(fRadii[index].fY));
- return dist <= SK_Scalar1;
+ // or :
+ // b^2*x^2 + a^2*y^2 <= (ab)^2
+ SkScalar dist = SkScalarMul(SkScalarSquare(canonicalPt.fX), SkScalarSquare(fRadii[index].fY)) +
+ SkScalarMul(SkScalarSquare(canonicalPt.fY), SkScalarSquare(fRadii[index].fX));
+ return dist <= SkScalarSquare(SkScalarMul(fRadii[index].fX, fRadii[index].fY));
+}
+
+bool SkRRect::contains(const SkRect& rect) const {
+ if (!this->getBounds().contains(rect)) {
+ // If 'rect' isn't contained by the RR's bounds then the
+ // RR definitely doesn't contain it
+ return false;
+ }
+
+ if (this->isRect()) {
+ // the prior test was sufficient
+ return true;
+ }
+
+ // At this point we know all four corners of 'rect' are inside the
+ // bounds of of this RR. Check to make sure all the corners are inside
+ // all the curves
+ return this->checkCornerContainment(rect.fLeft, rect.fTop) &&
+ this->checkCornerContainment(rect.fRight, rect.fTop) &&
+ this->checkCornerContainment(rect.fRight, rect.fBottom) &&
+ this->checkCornerContainment(rect.fLeft, rect.fBottom);
}
// There is a simplified version of this method in setRectXY