aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-26 18:16:27 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-11-26 18:16:27 +0000
commita8a3b3d9a027ad54ce20f8b4ed7c577a176b31ca (patch)
tree180cbc1350a82b98e612c0be12775efb304c63bc
parent5f0add3ad6e1d6129307276c81ba6624f92ca112 (diff)
check for bad enum use when adding contours
Review URL: https://codereview.appspot.com/6849103 git-svn-id: http://skia.googlecode.com/svn/trunk@6547 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkPath.h119
-rw-r--r--src/core/SkPath.cpp11
-rw-r--r--tests/PathTest.cpp1
3 files changed, 81 insertions, 50 deletions
diff --git a/include/core/SkPath.h b/include/core/SkPath.h
index cea964c177..942342dd56 100644
--- a/include/core/SkPath.h
+++ b/include/core/SkPath.h
@@ -510,9 +510,15 @@ public:
kCCW_Direction,
};
+ /**
+ * Return the opposite of the specified direction. kUnknown is its own
+ * opposite.
+ */
static Direction OppositeDirection(Direction dir) {
- static const Direction kOppositeDir[] = {kUnknown_Direction, kCCW_Direction, kCW_Direction};
- return kOppositeDir[dir];
+ static const Direction gOppositeDir[] = {
+ kUnknown_Direction, kCCW_Direction, kCW_Direction
+ };
+ return gOppositeDir[dir];
}
/**
@@ -527,12 +533,13 @@ public:
/**
* Returns true if the path's direction can be computed via
* cheapComputDirection() and if that computed direction matches the
- * specified direction.
+ * specified direction. If dir is kUnknown, returns true if the direction
+ * cannot be computed.
*/
bool cheapIsDirection(Direction dir) const {
- SkASSERT(kCW_Direction == dir || kCCW_Direction == dir);
- Direction computedDir;
- return this->cheapComputeDirection(&computedDir) && computedDir == dir;
+ Direction computedDir = kUnknown_Direction;
+ (void)this->cheapComputeDirection(&computedDir);
+ return computedDir == dir;
}
/** Returns true if the path specifies a rectangle. If so, and if isClosed is
@@ -546,44 +553,52 @@ public:
*/
bool isRect(bool* isClosed, Direction* direction) const;
- /** Add a closed rectangle contour to the path
- @param rect The rectangle to add as a closed contour to the path
- @param dir The direction to wind the rectangle's contour
- */
+ /**
+ * Add a closed rectangle contour to the path
+ * @param rect The rectangle to add as a closed contour to the path
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ */
void addRect(const SkRect& rect, Direction dir = kCW_Direction);
- /** Add a closed rectangle contour to the path
-
- @param left The left side of a rectangle to add as a closed contour
- to the path
- @param top The top of a rectangle to add as a closed contour to the
- path
- @param right The right side of a rectangle to add as a closed contour
- to the path
- @param bottom The bottom of a rectangle to add as a closed contour to
- the path
- @param dir The direction to wind the rectangle's contour
- */
+ /**
+ * Add a closed rectangle contour to the path
+ *
+ * @param left The left side of a rectangle to add as a closed contour
+ * to the path
+ * @param top The top of a rectangle to add as a closed contour to the
+ * path
+ * @param right The right side of a rectangle to add as a closed contour
+ * to the path
+ * @param bottom The bottom of a rectangle to add as a closed contour to
+ * the path
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ */
void addRect(SkScalar left, SkScalar top, SkScalar right, SkScalar bottom,
Direction dir = kCW_Direction);
- /** Add a closed oval contour to the path
-
- @param oval The bounding oval to add as a closed contour to the path
- @param dir The direction to wind the oval's contour
- */
+ /**
+ * Add a closed oval contour to the path
+ *
+ * @param oval The bounding oval to add as a closed contour to the path
+ * @param dir The direction to wind the oval's contour. Cannot be
+ * kUnknown_Direction.
+ */
void addOval(const SkRect& oval, Direction dir = kCW_Direction);
- /** Add a closed circle contour to the path
-
- @param x The x-coordinate of the center of a circle to add as a
- closed contour to the path
- @param y The y-coordinate of the center of a circle to add as a
- closed contour to the path
- @param radius The radius of a circle to add as a closed contour to the
- path
- @param dir The direction to wind the circle's contour
- */
+ /**
+ * Add a closed circle contour to the path
+ *
+ * @param x The x-coordinate of the center of a circle to add as a
+ * closed contour to the path
+ * @param y The y-coordinate of the center of a circle to add as a
+ * closed contour to the path
+ * @param radius The radius of a circle to add as a closed contour to the
+ * path
+ * @param dir The direction to wind the circle's contour. Cannot be
+ * kUnknown_Direction.
+ */
void addCircle(SkScalar x, SkScalar y, SkScalar radius,
Direction dir = kCW_Direction);
@@ -595,22 +610,26 @@ public:
*/
void addArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle);
- /** Add a closed round-rectangle contour to the path
- @param rect The bounds of a round-rectangle to add as a closed contour
- @param rx The x-radius of the rounded corners on the round-rectangle
- @param ry The y-radius of the rounded corners on the round-rectangle
- @param dir The direction to wind the round-rectangle's contour
- */
+ /**
+ * Add a closed round-rectangle contour to the path
+ * @param rect The bounds of a round-rectangle to add as a closed contour
+ * @param rx The x-radius of the rounded corners on the round-rectangle
+ * @param ry The y-radius of the rounded corners on the round-rectangle
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ */
void addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
Direction dir = kCW_Direction);
- /** Add a closed round-rectangle contour to the path. Each corner receives
- two radius values [X, Y]. The corners are ordered top-left, top-right,
- bottom-right, bottom-left.
- @param rect The bounds of a round-rectangle to add as a closed contour
- @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner
- @param dir The direction to wind the round-rectangle's contour
- */
+ /**
+ * Add a closed round-rectangle contour to the path. Each corner receives
+ * two radius values [X, Y]. The corners are ordered top-left, top-right,
+ * bottom-right, bottom-left.
+ * @param rect The bounds of a round-rectangle to add as a closed contour
+ * @param radii Array of 8 scalars, 4 [X,Y] pairs for each corner
+ * @param dir The direction to wind the rectangle's contour. Cannot be
+ * kUnknown_Direction.
+ */
void addRoundRect(const SkRect& rect, const SkScalar radii[],
Direction dir = kCW_Direction);
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index c3aa44e117..80ca3011e3 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -872,12 +872,17 @@ void SkPath::close() {
///////////////////////////////////////////////////////////////////////////////
+static void assert_known_direction(int dir) {
+ SkASSERT(SkPath::kCW_Direction == dir || SkPath::kCCW_Direction == dir);
+}
+
void SkPath::addRect(const SkRect& rect, Direction dir) {
this->addRect(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, dir);
}
void SkPath::addRect(SkScalar left, SkScalar top, SkScalar right,
SkScalar bottom, Direction dir) {
+ assert_known_direction(dir);
fDirection = this->hasOnlyMoveTos() ? dir : kUnknown_Direction;
SkAutoDisableDirectionCheck addc(this);
@@ -938,6 +943,8 @@ void SkPath::addPoly(const SkPoint pts[], int count, bool close) {
void SkPath::addRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry,
Direction dir) {
+ assert_known_direction(dir);
+
SkScalar w = rect.width();
SkScalar halfW = SkScalarHalf(w);
SkScalar h = rect.height();
@@ -1058,6 +1065,8 @@ static void add_corner_arc(SkPath* path, const SkRect& rect,
void SkPath::addRoundRect(const SkRect& rect, const SkScalar rad[],
Direction dir) {
+ assert_known_direction(dir);
+
// abort before we invoke SkAutoPathBoundsUpdate()
if (rect.isEmpty()) {
return;
@@ -1094,6 +1103,8 @@ bool SkPath::hasOnlyMoveTos() const {
}
void SkPath::addOval(const SkRect& oval, Direction dir) {
+ assert_known_direction(dir);
+
/* If addOval() is called after previous moveTo(),
this path is still marked as an oval. This is used to
fit into WebKit's calling sequences.
diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp
index f1894c3940..6f9a9e6465 100644
--- a/tests/PathTest.cpp
+++ b/tests/PathTest.cpp
@@ -375,6 +375,7 @@ static void test_direction(skiatest::Reporter* reporter) {
REPORTER_ASSERT(reporter, !path.cheapComputeDirection(NULL));
REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCW_Direction));
REPORTER_ASSERT(reporter, !path.cheapIsDirection(SkPath::kCCW_Direction));
+ REPORTER_ASSERT(reporter, path.cheapIsDirection(SkPath::kUnknown_Direction));
static const char* gDegen[] = {
"M 10 10",