Chromium Code Reviews| Index: src/pathops/SkPathOpsTightBounds.cpp |
| diff --git a/src/pathops/SkPathOpsTightBounds.cpp b/src/pathops/SkPathOpsTightBounds.cpp |
| index 60f18cfbbc7842c15a212c6d12a14ce451937a55..f9062588b97a87dfbbba84006c4a1a85190c6825 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); |
|
f(malita)
2016/10/05 18:51:25
Doesn't between() == true => well behaved?
Maybe
caryclark
2016/10/05 19:16:35
No, it is me who's logic is flipped. Fixed.
|
| + 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; |
| } |