Index: src/pathops/SkPathOpsTightBounds.cpp |
diff --git a/src/pathops/SkPathOpsTightBounds.cpp b/src/pathops/SkPathOpsTightBounds.cpp |
index 60f18cfbbc7842c15a212c6d12a14ce451937a55..d748ff538afae063fda7cae7d54fcd346cfa7af7 100644 |
--- a/src/pathops/SkPathOpsTightBounds.cpp |
+++ b/src/pathops/SkPathOpsTightBounds.cpp |
@@ -8,6 +8,45 @@ |
#include "SkPathOpsCommon.h" |
bool TightBounds(const SkPath& path, SkRect* result) { |
+ SkPath::RawIter iter(path); |
+ SkRect moveBounds = { SK_ScalarMax, SK_ScalarMax, SK_ScalarMin, SK_ScalarMin }; |
+ bool wellBehaved = true; |
+ SkPath::Verb verb; |
+ do { |
+ SkPoint pts[4]; |
+ verb = iter.next(pts); |
+ switch (verb) { |
+ case SkPath::kMove_Verb: |
+ moveBounds.fLeft = SkTMin(moveBounds.fLeft, pts[0].fX); |
+ moveBounds.fTop = SkTMin(moveBounds.fTop, pts[0].fY); |
+ moveBounds.fRight = SkTMax(moveBounds.fRight, pts[0].fX); |
+ moveBounds.fBottom = SkTMax(moveBounds.fBottom, pts[0].fY); |
+ break; |
+ case SkPath::kQuad_Verb: |
+ case SkPath::kConic_Verb: |
+ if (!wellBehaved) { |
+ break; |
+ } |
+ wellBehaved &= between(pts[0].fX, pts[1].fX, pts[2].fX); |
+ wellBehaved &= between(pts[0].fY, pts[1].fY, pts[2].fY); |
+ break; |
+ case SkPath::kCubic_Verb: |
+ if (!wellBehaved) { |
+ break; |
+ } |
+ wellBehaved &= between(pts[0].fX, pts[1].fX, pts[3].fX); |
+ wellBehaved &= between(pts[0].fY, pts[1].fY, pts[3].fY); |
+ wellBehaved &= between(pts[0].fX, pts[2].fX, pts[3].fX); |
+ wellBehaved &= between(pts[0].fY, pts[2].fY, pts[3].fY); |
+ break; |
+ default: |
+ break; |
+ } |
+ } while (verb != SkPath::kDone_Verb); |
+ if (wellBehaved) { |
+ *result = path.getBounds(); |
+ return true; |
+ } |
SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune |
SkOpContour contour; |
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour); |
@@ -28,7 +67,7 @@ bool TightBounds(const SkPath& path, SkRect* result) { |
return false; |
} |
if (!SortContourList(&contourList, false, false)) { |
- result->setEmpty(); |
+ *result = moveBounds; |
return true; |
} |
SkOpContour* current = contourList; |
@@ -37,5 +76,8 @@ bool TightBounds(const SkPath& path, SkRect* result) { |
bounds.add(current->bounds()); |
} |
*result = bounds; |
+ if (!moveBounds.isEmpty()) { |
+ result->join(moveBounds); |
+ } |
return true; |
} |