1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkPathPriv_DEFINED 9 #define SkPathPriv_DEFINED 10 11 #include "SkPath.h" 12 13 class SkPathPriv { 14 public: 15 enum FirstDirection { 16 kCW_FirstDirection, // == SkPath::kCW_Direction 17 kCCW_FirstDirection, // == SkPath::kCCW_Direction 18 kUnknown_FirstDirection, 19 }; 20 AsFirstDirection(SkPath::Direction dir)21 static FirstDirection AsFirstDirection(SkPath::Direction dir) { 22 // since we agree numerically for the values in Direction, we can just cast. 23 return (FirstDirection)dir; 24 } 25 26 /** 27 * Return the opposite of the specified direction. kUnknown is its own 28 * opposite. 29 */ OppositeFirstDirection(FirstDirection dir)30 static FirstDirection OppositeFirstDirection(FirstDirection dir) { 31 static const FirstDirection gOppositeDir[] = { 32 kCCW_FirstDirection, kCW_FirstDirection, kUnknown_FirstDirection, 33 }; 34 return gOppositeDir[dir]; 35 } 36 37 /** 38 * Tries to quickly compute the direction of the first non-degenerate 39 * contour. If it can be computed, return true and set dir to that 40 * direction. If it cannot be (quickly) determined, return false and ignore 41 * the dir parameter. If the direction was determined, it is cached to make 42 * subsequent calls return quickly. 43 */ 44 static bool CheapComputeFirstDirection(const SkPath&, FirstDirection* dir); 45 46 /** 47 * Returns true if the path's direction can be computed via 48 * cheapComputDirection() and if that computed direction matches the 49 * specified direction. If dir is kUnknown, returns true if the direction 50 * cannot be computed. 51 */ CheapIsFirstDirection(const SkPath & path,FirstDirection dir)52 static bool CheapIsFirstDirection(const SkPath& path, FirstDirection dir) { 53 FirstDirection computedDir = kUnknown_FirstDirection; 54 (void)CheapComputeFirstDirection(path, &computedDir); 55 return computedDir == dir; 56 } 57 IsClosedSingleContour(const SkPath & path)58 static bool IsClosedSingleContour(const SkPath& path) { 59 int verbCount = path.countVerbs(); 60 if (verbCount == 0) 61 return false; 62 int moveCount = 0; 63 auto verbs = path.fPathRef->verbs(); 64 for (int i = 0; i < verbCount; i++) { 65 switch (verbs[~i]) { // verbs are stored backwards; we use [~i] to get the i'th verb 66 case SkPath::Verb::kMove_Verb: 67 moveCount += 1; 68 if (moveCount > 1) { 69 return false; 70 } 71 break; 72 case SkPath::Verb::kClose_Verb: 73 if (i == verbCount - 1) { 74 return true; 75 } 76 return false; 77 default: break; 78 } 79 } 80 return false; 81 } 82 AddGenIDChangeListener(const SkPath & path,SkPathRef::GenIDChangeListener * listener)83 static void AddGenIDChangeListener(const SkPath& path, SkPathRef::GenIDChangeListener* listener) { 84 path.fPathRef->addGenIDChangeListener(listener); 85 } 86 }; 87 88 #endif 89