diff options
-rw-r--r-- | include/core/SkPath.h | 17 | ||||
-rw-r--r-- | src/core/SkPath.cpp | 76 | ||||
-rw-r--r-- | tests/PathTest.cpp | 192 |
3 files changed, 0 insertions, 285 deletions
diff --git a/include/core/SkPath.h b/include/core/SkPath.h index 025e7099b5..01b5488e6d 100644 --- a/include/core/SkPath.h +++ b/include/core/SkPath.h @@ -161,18 +161,6 @@ public: this->setConvexity(isConvex ? kConvex_Convexity : kConcave_Convexity); } - /** Returns true if the path is an oval. - * - * @param rect returns the bounding rect of this oval. It's a circle - * if the height and width are the same. - * - * @return true if this path is an oval. - * Tracking whether a path is an oval is considered an - * optimization for performance and so some paths that are in - * fact ovals can report false. - */ - bool isOval(SkRect* rect) const; - /** Clear any lines and curves from the path, making it empty. This frees up internal storage associated with those segments. This does NOT change the fill-type setting nor isConvex @@ -759,8 +747,6 @@ private: uint8_t fSegmentMask; mutable uint8_t fBoundsIsDirty; mutable uint8_t fConvexity; - - mutable SkBool8 fIsOval; #ifdef SK_BUILD_FOR_ANDROID uint32_t fGenerationID; const SkPath* fSourcePath; @@ -792,10 +778,7 @@ private: // inline void injectMoveToIfNeeded(); - inline bool hasOnlyMoveTos() const; - friend class SkAutoPathBoundsUpdate; - friend class SkAutoDisableOvalCheck; }; #endif diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp index 94246201ea..7f58ae347e 100644 --- a/src/core/SkPath.cpp +++ b/src/core/SkPath.cpp @@ -32,21 +32,6 @@ static bool is_degenerate(const SkPath& path) { return SkPath::kDone_Verb == iter.next(pts); } -class SkAutoDisableOvalCheck { -public: - SkAutoDisableOvalCheck(SkPath* path) : fPath(path) { - fSaved = fPath->fIsOval; - } - - ~SkAutoDisableOvalCheck() { - fPath->fIsOval = fSaved; - } - -private: - SkPath* fPath; - bool fSaved; -}; - /* This guy's constructor/destructor bracket a path editing operation. It is used when we know the bounds of the amount we are going to add to the path (usually a new contour, but not required). @@ -134,7 +119,6 @@ SkPath::SkPath() fConvexity = kUnknown_Convexity; fSegmentMask = 0; fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE; - fIsOval = false; #ifdef SK_BUILD_FOR_ANDROID fGenerationID = 0; fSourcePath = NULL; @@ -167,7 +151,6 @@ SkPath& SkPath::operator=(const SkPath& src) { fConvexity = src.fConvexity; fSegmentMask = src.fSegmentMask; fLastMoveToIndex = src.fLastMoveToIndex; - fIsOval = src.fIsOval; GEN_ID_INC; } SkDEBUGCODE(this->validate();) @@ -199,7 +182,6 @@ void SkPath::swap(SkPath& other) { SkTSwap<uint8_t>(fConvexity, other.fConvexity); SkTSwap<uint8_t>(fSegmentMask, other.fSegmentMask); SkTSwap<int>(fLastMoveToIndex, other.fLastMoveToIndex); - SkTSwap<SkBool8>(fIsOval, other.fIsOval); GEN_ID_INC; } } @@ -228,7 +210,6 @@ void SkPath::reset() { fConvexity = kUnknown_Convexity; fSegmentMask = 0; fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE; - fIsOval = false; } void SkPath::rewind() { @@ -241,7 +222,6 @@ void SkPath::rewind() { fBoundsIsDirty = true; fSegmentMask = 0; fLastMoveToIndex = INITIAL_LASTMOVETOINDEX_VALUE; - fIsOval = false; } bool SkPath::isEmpty() const { @@ -408,7 +388,6 @@ void SkPath::setLastPt(SkScalar x, SkScalar y) { if (count == 0) { this->moveTo(x, y); } else { - fIsOval = false; fPts[count - 1].set(x, y); GEN_ID_INC; } @@ -436,7 +415,6 @@ void SkPath::setConvexity(Convexity c) { do { \ fBoundsIsDirty = true; \ fConvexity = kUnknown_Convexity; \ - fIsOval = false; \ } while (0) #define DIRTY_AFTER_EDIT_NO_CONVEXITY_CHANGE \ @@ -751,31 +729,7 @@ void SkPath::addRoundRect(const SkRect& rect, const SkScalar rad[], this->close(); } -bool SkPath::hasOnlyMoveTos() const { - const uint8_t* verbs = fVerbs.begin(); - const uint8_t* verbStop = fVerbs.end(); - while (verbs != verbStop) { - if (*verbs == kLine_Verb || - *verbs == kQuad_Verb || - *verbs == kCubic_Verb) { - return false; - } - ++verbs; - } - return true; -} - void SkPath::addOval(const SkRect& oval, 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. - We can't simply check isEmpty() in this case, as additional - moveTo() would mark the path non empty. - */ - fIsOval = hasOnlyMoveTos(); - - SkAutoDisableOvalCheck adoc(this); - SkAutoPathBoundsUpdate apbu(this, oval); SkScalar cx = oval.centerX(); @@ -841,17 +795,6 @@ void SkPath::addOval(const SkRect& oval, Direction dir) { this->close(); } -bool SkPath::isOval(SkRect* rect) const { - if (isEmpty() || !fIsOval) { - return false; - } - - if (rect) { - *rect = getBounds(); - } - return true; -} - void SkPath::addCircle(SkScalar x, SkScalar y, SkScalar r, Direction dir) { if (r > 0) { SkRect rect; @@ -1027,8 +970,6 @@ void SkPath::addPath(const SkPath& path, SkScalar dx, SkScalar dy) { void SkPath::addPath(const SkPath& path, const SkMatrix& matrix) { this->incReserve(path.fPts.count()); - fIsOval = false; - RawIter iter(path); SkPoint pts[4]; Verb verb; @@ -1082,8 +1023,6 @@ void SkPath::pathTo(const SkPath& path) { this->incReserve(vcount); - fIsOval = false; - const uint8_t* verbs = path.fVerbs.begin(); const SkPoint* pts = path.fPts.begin() + 1; // 1 for the initial moveTo @@ -1116,8 +1055,6 @@ void SkPath::reversePathTo(const SkPath& path) { this->incReserve(vcount); - fIsOval = false; - const uint8_t* verbs = path.fVerbs.begin(); const SkPoint* pts = path.fPts.begin(); @@ -1158,8 +1095,6 @@ void SkPath::reverseAddPath(const SkPath& src) { const uint8_t* startVerbs = src.fVerbs.begin(); const uint8_t* verbs = src.fVerbs.end(); - fIsOval = false; - bool needMove = true; bool needClose = false; while (verbs > startVerbs) { @@ -1293,19 +1228,8 @@ void SkPath::transform(const SkMatrix& matrix, SkPath* dst) const { dst->fFillType = fFillType; dst->fSegmentMask = fSegmentMask; dst->fConvexity = fConvexity; - dst->fIsOval = fIsOval; } - matrix.mapPoints(dst->fPts.begin(), fPts.begin(), fPts.count()); - - // isOval() must be called after dst->fPts are changed. - // otherwise, isOval() would call validate() implicitly and - // at that time it finds its control points are not bound by fBounds. - if (this->isOval(NULL)) { - // It's an oval only if it stays a rect. - dst->fIsOval = matrix.rectStaysRect(); - } - SkDEBUGCODE(dst->validate();) } } diff --git a/tests/PathTest.cpp b/tests/PathTest.cpp index c3f4a4f509..d88454795f 100644 --- a/tests/PathTest.cpp +++ b/tests/PathTest.cpp @@ -1053,196 +1053,6 @@ static void test_raw_iter(skiatest::Reporter* reporter) { } } -static void check_for_circle(skiatest::Reporter* reporter, - const SkPath& path, bool expected) { - SkRect rect; - REPORTER_ASSERT(reporter, path.isOval(&rect) == expected); - if (expected) { - REPORTER_ASSERT(reporter, rect.height() == rect.width()); - } -} - -static void test_circle_skew(skiatest::Reporter* reporter, - const SkPath& path) { - SkPath tmp; - - SkMatrix m; - m.setSkew(SkIntToScalar(3), SkIntToScalar(5)); - path.transform(m, &tmp); - check_for_circle(reporter, tmp, false); -} - -static void test_circle_translate(skiatest::Reporter* reporter, - const SkPath& path) { - SkPath tmp; - - // translate at small offset - SkMatrix m; - m.setTranslate(SkIntToScalar(15), SkIntToScalar(15)); - path.transform(m, &tmp); - check_for_circle(reporter, tmp, true); - - tmp.reset(); - m.reset(); - - // translate at a relatively big offset - m.setTranslate(SkIntToScalar(1000), SkIntToScalar(1000)); - path.transform(m, &tmp); - check_for_circle(reporter, tmp, true); -} - -static void test_circle_rotate(skiatest::Reporter* reporter, - const SkPath& path) { - for (int angle = 0; angle < 360; ++angle) { - SkPath tmp; - SkMatrix m; - m.setRotate(SkIntToScalar(angle)); - path.transform(m, &tmp); - - // TODO: a rotated circle whose rotated angle is not a mutiple of 90 - // degrees is not an oval anymore, this can be improved. we made this - // for the simplicity of our implementation. - if (angle % 90 == 0) { - check_for_circle(reporter, tmp, true); - } else { - check_for_circle(reporter, tmp, false); - } - } -} - -static void test_circle_with_direction(skiatest::Reporter* reporter, - SkPath::Direction dir) { - SkPath path; - - // circle at origin - path.addCircle(0, 0, SkIntToScalar(20), dir); - check_for_circle(reporter, path, true); - test_circle_rotate(reporter, path); - test_circle_translate(reporter, path); - test_circle_skew(reporter, path); - - // circle at an offset at (10, 10) - path.reset(); - path.addCircle(SkIntToScalar(10), SkIntToScalar(10), - SkIntToScalar(20), dir); - check_for_circle(reporter, path, true); - test_circle_rotate(reporter, path); - test_circle_translate(reporter, path); - test_circle_skew(reporter, path); -} - -static void test_circle_with_add_paths(skiatest::Reporter* reporter) { - SkPath path; - SkPath circle; - SkPath rect; - SkPath empty; - - circle.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction); - rect.addRect(SkIntToScalar(5), SkIntToScalar(5), - SkIntToScalar(20), SkIntToScalar(20), SkPath::kCW_Direction); - - SkMatrix translate; - translate.setTranslate(SkIntToScalar(12), SkIntToScalar(12)); - - // For simplicity, all the path concatenation related operations - // would mark it non-circle, though in theory it's still a circle. - - // empty + circle (translate) - path = empty; - path.addPath(circle, translate); - check_for_circle(reporter, path, false); - - // circle + empty (translate) - path = circle; - path.addPath(empty, translate); - check_for_circle(reporter, path, false); - - // test reverseAddPath - path = circle; - path.reverseAddPath(rect); - check_for_circle(reporter, path, false); -} - -static void test_circle(skiatest::Reporter* reporter) { - test_circle_with_direction(reporter, SkPath::kCW_Direction); - test_circle_with_direction(reporter, SkPath::kCCW_Direction); - - // multiple addCircle() - SkPath path; - path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction); - path.addCircle(0, 0, SkIntToScalar(20), SkPath::kCW_Direction); - check_for_circle(reporter, path, false); - - // some extra lineTo() would make isOval() fail - path.reset(); - path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction); - path.lineTo(0, 0); - check_for_circle(reporter, path, false); - - // not back to the original point - path.reset(); - path.addCircle(0, 0, SkIntToScalar(10), SkPath::kCW_Direction); - path.setLastPt(SkIntToScalar(5), SkIntToScalar(5)); - check_for_circle(reporter, path, false); - - test_circle_with_add_paths(reporter); -} - -static void test_oval(skiatest::Reporter* reporter) { - SkRect rect; - SkMatrix m; - SkPath path; - - rect = SkRect::MakeWH(SkIntToScalar(30), SkIntToScalar(50)); - path.addOval(rect); - - REPORTER_ASSERT(reporter, path.isOval(NULL)); - - m.setRotate(90); - SkPath tmp; - path.transform(m, &tmp); - // an oval rotated 90 degrees is still an oval. - REPORTER_ASSERT(reporter, tmp.isOval(NULL)); - - m.reset(); - m.setRotate(30); - tmp.reset(); - path.transform(m, &tmp); - // an oval rotated 30 degrees is not an oval anymore. - REPORTER_ASSERT(reporter, !tmp.isOval(NULL)); - - // since empty path being transformed. - path.reset(); - tmp.reset(); - m.reset(); - path.transform(m, &tmp); - REPORTER_ASSERT(reporter, !tmp.isOval(NULL)); - - // empty path is not an oval - tmp.reset(); - REPORTER_ASSERT(reporter, !tmp.isOval(NULL)); - - // only has moveTo()s - tmp.reset(); - tmp.moveTo(0, 0); - tmp.moveTo(SkIntToScalar(10), SkIntToScalar(10)); - REPORTER_ASSERT(reporter, !tmp.isOval(NULL)); - - // mimic WebKit's calling convention, - // call moveTo() first and then call addOval() - path.reset(); - path.moveTo(0, 0); - path.addOval(rect); - REPORTER_ASSERT(reporter, path.isOval(NULL)); - - // copy path - path.reset(); - tmp.reset(); - tmp.addOval(rect); - path = tmp; - REPORTER_ASSERT(reporter, path.isOval(NULL)); -} - void TestPath(skiatest::Reporter* reporter) { { SkSize size; @@ -1328,8 +1138,6 @@ void TestPath(skiatest::Reporter* reporter) { test_bounds(reporter); test_iter(reporter); test_raw_iter(reporter); - test_circle(reporter); - test_oval(reporter); } #include "TestClassDef.h" |