From a8a3b3d9a027ad54ce20f8b4ed7c577a176b31ca Mon Sep 17 00:00:00 2001 From: "reed@google.com" Date: Mon, 26 Nov 2012 18:16:27 +0000 Subject: 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 --- include/core/SkPath.h | 119 +++++++++++++++++++++++++++++--------------------- src/core/SkPath.cpp | 11 +++++ tests/PathTest.cpp | 1 + 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", -- cgit v1.2.3