Index: src/core/SkPath.cpp |
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp |
index 5cd6316c7ff3556e8aad71efd11785f642f6372a..84181a38e7828a58cf99f5d6d55a3df7f5aaeae0 100644 |
--- a/src/core/SkPath.cpp |
+++ b/src/core/SkPath.cpp |
@@ -3249,3 +3249,124 @@ int SkPath::ConvertConicToQuads(const SkPoint& p0, const SkPoint& p1, const SkPo |
const SkConic conic(p0, p1, p2, w); |
return conic.chopIntoQuadsPOW2(pts, pow2); |
} |
+ |
+bool SkPathPriv::IsSimpleClosedRect(const SkPath& path, SkRect* rect, SkPath::Direction* direction, |
+ unsigned* start) { |
+ if (path.getSegmentMasks() != SkPath::kLine_SegmentMask) { |
+ return false; |
+ } |
+ SkPath::RawIter iter(path); |
+ SkPoint verbPts[4]; |
+ SkPath::Verb v; |
+ SkPoint rectPts[5]; |
+ int rectPtCnt = 0; |
+ while ((v = iter.next(verbPts)) != SkPath::kDone_Verb) { |
+ switch (v) { |
+ case SkPath::kMove_Verb: |
+ if (0 != rectPtCnt) { |
+ return false; |
+ } |
+ rectPts[0] = verbPts[0]; |
+ ++rectPtCnt; |
+ break; |
+ case SkPath::kLine_Verb: |
+ if (5 == rectPtCnt) { |
+ return false; |
+ } |
+ rectPts[rectPtCnt] = verbPts[1]; |
+ ++rectPtCnt; |
+ break; |
+ case SkPath::kClose_Verb: |
+ if (4 == rectPtCnt) { |
+ rectPts[4] = rectPts[0]; |
+ rectPtCnt = 5; |
+ } |
+ break; |
+ default: |
+ return false; |
+ } |
+ } |
+ if (rectPtCnt < 5) { |
+ return false; |
+ } |
+ if (rectPts[0] != rectPts[4]) { |
+ return false; |
+ } |
+ int verticalCnt = 0; |
+ int horizontalCnt = 0; |
+ // dirs are 0 - right, 1 - down, 2 - left, 3 - up. |
+ int firstDir; |
+ int secondDir; |
+ SkRect tempRect; |
+ for (int i = 0; i < 4; ++i) { |
+ int sameCnt = 0; |
+ if (rectPts[i].fX == rectPts[i + 1].fX) { |
+ verticalCnt += 1; |
+ sameCnt = 1; |
+ if (0 == i) { |
+ if (rectPts[1].fY > rectPts[0].fY) { |
+ firstDir = 1; |
+ tempRect.fTop = rectPts[0].fY; |
+ tempRect.fBottom = rectPts[1].fY; |
+ } else { |
+ firstDir = 3; |
+ tempRect.fTop = rectPts[1].fY; |
+ tempRect.fBottom = rectPts[0].fY; |
+ } |
+ } else if (1 == i) { |
+ if (rectPts[2].fY > rectPts[1].fY) { |
+ secondDir = 1; |
+ tempRect.fTop = rectPts[1].fY; |
+ tempRect.fBottom = rectPts[2].fY; |
+ } else { |
+ secondDir = 3; |
+ tempRect.fTop = rectPts[2].fY; |
+ tempRect.fBottom = rectPts[1].fY; |
+ } |
+ } |
+ } |
+ if (rectPts[i].fY == rectPts[i + 1].fY) { |
+ horizontalCnt += 1; |
+ sameCnt += 1; |
+ if (0 == i) { |
+ if (rectPts[1].fX > rectPts[0].fX) { |
+ firstDir = 0; |
+ tempRect.fLeft = rectPts[0].fX; |
+ tempRect.fRight = rectPts[1].fX; |
+ } else { |
+ firstDir = 2; |
+ tempRect.fLeft = rectPts[1].fX; |
+ tempRect.fRight = rectPts[0].fX; |
+ } |
+ } else if (1 == i) { |
+ if (rectPts[2].fX > rectPts[1].fX) { |
+ secondDir = 0; |
+ tempRect.fLeft = rectPts[1].fX; |
+ tempRect.fRight = rectPts[2].fX; |
+ } else { |
+ secondDir = 2; |
+ tempRect.fLeft = rectPts[2].fX; |
+ tempRect.fRight = rectPts[1].fX; |
+ } |
+ } |
+ } |
+ if (sameCnt != 1) { |
+ return false; |
+ } |
+ } |
+ if (2 != horizontalCnt || 2 != verticalCnt) { |
+ return false; |
+ } |
+ // low bit indicates a vertical dir |
+ SkASSERT((firstDir ^ secondDir) & 0b1); |
+ if (((firstDir + 1) & 0b11) == secondDir) { |
+ *direction = SkPath::kCW_Direction; |
+ *start = firstDir; |
+ } else { |
+ SkASSERT(((secondDir + 1) & 0b11) == firstDir); |
+ *direction = SkPath::kCCW_Direction; |
+ *start = secondDir; |
+ } |
+ *rect = tempRect; |
+ return true; |
+} |