| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2014 Google Inc. | 2  * Copyright 2014 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 #include "SkMatrix.h" | 8 #include "SkMatrix.h" | 
| 9 #include "SkOpEdgeBuilder.h" | 9 #include "SkOpEdgeBuilder.h" | 
| 10 #include "SkPathPriv.h" | 10 #include "SkPathPriv.h" | 
| 11 #include "SkPathOps.h" | 11 #include "SkPathOps.h" | 
| 12 #include "SkPathOpsCommon.h" | 12 #include "SkPathOpsCommon.h" | 
| 13 | 13 | 
| 14 static bool one_contour(const SkPath& path) { | 14 static bool one_contour(const SkPath& path) { | 
| 15     SkChunkAlloc allocator(256); | 15     SkChunkAlloc allocator(256); | 
| 16     int verbCount = path.countVerbs(); | 16     int verbCount = path.countVerbs(); | 
| 17     uint8_t* verbs = (uint8_t*) allocator.alloc(sizeof(uint8_t) * verbCount, | 17     uint8_t* verbs = (uint8_t*) allocator.alloc(sizeof(uint8_t) * verbCount, | 
| 18             SkChunkAlloc::kThrow_AllocFailType); | 18             SkChunkAlloc::kThrow_AllocFailType); | 
| 19     (void) path.getVerbs(verbs, verbCount); | 19     (void) path.getVerbs(verbs, verbCount); | 
| 20     for (int index = 1; index < verbCount; ++index) { | 20     for (int index = 1; index < verbCount; ++index) { | 
| 21         if (verbs[index] == SkPath::kMove_Verb) { | 21         if (verbs[index] == SkPath::kMove_Verb) { | 
| 22             return false; | 22             return false; | 
| 23         } | 23         } | 
| 24     } | 24     } | 
| 25     return true; | 25     return true; | 
| 26 } | 26 } | 
| 27 | 27 | 
| 28 bool FixWinding(SkPath* path) { | 28 void SkOpBuilder::ReversePath(SkPath* path) { | 
|  | 29     SkPath temp; | 
|  | 30     SkPoint lastPt; | 
|  | 31     SkAssertResult(path->getLastPt(&lastPt)); | 
|  | 32     temp.moveTo(lastPt); | 
|  | 33     temp.reversePathTo(*path); | 
|  | 34     temp.close(); | 
|  | 35     *path = temp; | 
|  | 36 } | 
|  | 37 | 
|  | 38 bool SkOpBuilder::FixWinding(SkPath* path) { | 
| 29     SkPath::FillType fillType = path->getFillType(); | 39     SkPath::FillType fillType = path->getFillType(); | 
| 30     if (fillType == SkPath::kInverseEvenOdd_FillType) { | 40     if (fillType == SkPath::kInverseEvenOdd_FillType) { | 
| 31         fillType = SkPath::kInverseWinding_FillType; | 41         fillType = SkPath::kInverseWinding_FillType; | 
| 32     } else if (fillType == SkPath::kEvenOdd_FillType) { | 42     } else if (fillType == SkPath::kEvenOdd_FillType) { | 
| 33         fillType = SkPath::kWinding_FillType; | 43         fillType = SkPath::kWinding_FillType; | 
| 34     } | 44     } | 
| 35     SkPathPriv::FirstDirection dir; | 45     SkPathPriv::FirstDirection dir; | 
| 36     if (one_contour(*path) && SkPathPriv::CheapComputeFirstDirection(*path, &dir
     )) { | 46     if (one_contour(*path) && SkPathPriv::CheapComputeFirstDirection(*path, &dir
     )) { | 
| 37         if (dir != SkPathPriv::kCCW_FirstDirection) { | 47         if (dir != SkPathPriv::kCCW_FirstDirection) { | 
| 38             SkPath temp; | 48             ReversePath(path); | 
| 39             temp.reverseAddPath(*path); |  | 
| 40             *path = temp; |  | 
| 41         } | 49         } | 
| 42         path->setFillType(fillType); | 50         path->setFillType(fillType); | 
| 43         return true; | 51         return true; | 
| 44     } | 52     } | 
| 45     SkChunkAlloc allocator(4096); | 53     SkChunkAlloc allocator(4096); | 
| 46     SkOpContourHead contourHead; | 54     SkOpContourHead contourHead; | 
| 47     SkOpGlobalState globalState(&contourHead, &allocator  SkDEBUGPARAMS(false) | 55     SkOpGlobalState globalState(&contourHead, &allocator  SkDEBUGPARAMS(false) | 
| 48             SkDEBUGPARAMS(nullptr)); | 56             SkDEBUGPARAMS(nullptr)); | 
| 49     SkOpEdgeBuilder builder(*path, &contourHead, &globalState); | 57     SkOpEdgeBuilder builder(*path, &contourHead, &globalState); | 
| 50     if (builder.unparseable() || !builder.finish()) { | 58     if (builder.unparseable() || !builder.finish()) { | 
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 126         // If all paths are convex, track direction, reversing as needed. | 134         // If all paths are convex, track direction, reversing as needed. | 
| 127         if (test->isConvex()) { | 135         if (test->isConvex()) { | 
| 128             SkPathPriv::FirstDirection dir; | 136             SkPathPriv::FirstDirection dir; | 
| 129             if (!SkPathPriv::CheapComputeFirstDirection(*test, &dir)) { | 137             if (!SkPathPriv::CheapComputeFirstDirection(*test, &dir)) { | 
| 130                 allUnion = false; | 138                 allUnion = false; | 
| 131                 break; | 139                 break; | 
| 132             } | 140             } | 
| 133             if (firstDir == SkPathPriv::kUnknown_FirstDirection) { | 141             if (firstDir == SkPathPriv::kUnknown_FirstDirection) { | 
| 134                 firstDir = dir; | 142                 firstDir = dir; | 
| 135             } else if (firstDir != dir) { | 143             } else if (firstDir != dir) { | 
| 136                 SkPath temp; | 144                 ReversePath(test); | 
| 137                 temp.reverseAddPath(*test); |  | 
| 138                 *test = temp; |  | 
| 139             } | 145             } | 
| 140             continue; | 146             continue; | 
| 141         } | 147         } | 
| 142         // If the path is not convex but its bounds do not intersect the others,
      simplify is enough. | 148         // If the path is not convex but its bounds do not intersect the others,
      simplify is enough. | 
| 143         const SkRect& testBounds = test->getBounds(); | 149         const SkRect& testBounds = test->getBounds(); | 
| 144         for (int inner = 0; inner < index; ++inner) { | 150         for (int inner = 0; inner < index; ++inner) { | 
| 145             // OPTIMIZE: check to see if the contour bounds do not intersect oth
     er contour bounds? | 151             // OPTIMIZE: check to see if the contour bounds do not intersect oth
     er contour bounds? | 
| 146             if (SkRect::Intersects(fPathRefs[inner].getBounds(), testBounds)) { | 152             if (SkRect::Intersects(fPathRefs[inner].getBounds(), testBounds)) { | 
| 147                 allUnion = false; | 153                 allUnion = false; | 
| 148                 break; | 154                 break; | 
| (...skipping 28 matching lines...) Expand all  Loading... | 
| 177             sum.addPath(fPathRefs[index]); | 183             sum.addPath(fPathRefs[index]); | 
| 178         } | 184         } | 
| 179     } | 185     } | 
| 180     reset(); | 186     reset(); | 
| 181     bool success = Simplify(sum, result); | 187     bool success = Simplify(sum, result); | 
| 182     if (!success) { | 188     if (!success) { | 
| 183         *result = original; | 189         *result = original; | 
| 184     } | 190     } | 
| 185     return success; | 191     return success; | 
| 186 } | 192 } | 
| OLD | NEW | 
|---|