OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
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 "SkBuffer.h" | 8 #include "SkBuffer.h" |
9 #include "SkErrorInternals.h" | 9 #include "SkErrorInternals.h" |
10 #include "SkGeometry.h" | 10 #include "SkGeometry.h" |
(...skipping 2111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2122 | 2122 |
2123 return kStraight_DirChange; | 2123 return kStraight_DirChange; |
2124 } | 2124 } |
2125 | 2125 |
2126 // only valid for a single contour | 2126 // only valid for a single contour |
2127 struct Convexicator { | 2127 struct Convexicator { |
2128 Convexicator() | 2128 Convexicator() |
2129 : fPtCount(0) | 2129 : fPtCount(0) |
2130 , fConvexity(SkPath::kConvex_Convexity) | 2130 , fConvexity(SkPath::kConvex_Convexity) |
2131 , fDirection(SkPath::kUnknown_Direction) | 2131 , fDirection(SkPath::kUnknown_Direction) |
2132 , fIsFinite(true) { | 2132 , fIsFinite(true) |
| 2133 , fIsCurve(false) { |
2133 fExpectedDir = kInvalid_DirChange; | 2134 fExpectedDir = kInvalid_DirChange; |
2134 // warnings | 2135 // warnings |
2135 fLastPt.set(0, 0); | 2136 fLastPt.set(0, 0); |
2136 fCurrPt.set(0, 0); | 2137 fCurrPt.set(0, 0); |
2137 fLastVec.set(0, 0); | 2138 fLastVec.set(0, 0); |
2138 fFirstVec.set(0, 0); | 2139 fFirstVec.set(0, 0); |
2139 | 2140 |
2140 fDx = fDy = 0; | 2141 fDx = fDy = 0; |
2141 fSx = fSy = kValueNeverReturnedBySign; | 2142 fSx = fSy = kValueNeverReturnedBySign; |
2142 } | 2143 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 void close() { | 2187 void close() { |
2187 if (fPtCount > 2) { | 2188 if (fPtCount > 2) { |
2188 this->addVec(fFirstVec); | 2189 this->addVec(fFirstVec); |
2189 } | 2190 } |
2190 } | 2191 } |
2191 | 2192 |
2192 bool isFinite() const { | 2193 bool isFinite() const { |
2193 return fIsFinite; | 2194 return fIsFinite; |
2194 } | 2195 } |
2195 | 2196 |
| 2197 void setCurve(bool isCurve) { |
| 2198 fIsCurve = isCurve; |
| 2199 } |
| 2200 |
2196 private: | 2201 private: |
2197 void addVec(const SkVector& vec) { | 2202 void addVec(const SkVector& vec) { |
2198 SkASSERT(vec.fX || vec.fY); | 2203 SkASSERT(vec.fX || vec.fY); |
2199 DirChange dir = direction_change(fLastPt, fCurrPt, fLastVec, vec); | 2204 DirChange dir = direction_change(fLastPt, fCurrPt, fLastVec, vec); |
2200 switch (dir) { | 2205 switch (dir) { |
2201 case kLeft_DirChange: // fall through | 2206 case kLeft_DirChange: // fall through |
2202 case kRight_DirChange: | 2207 case kRight_DirChange: |
2203 if (kInvalid_DirChange == fExpectedDir) { | 2208 if (kInvalid_DirChange == fExpectedDir) { |
2204 fExpectedDir = dir; | 2209 fExpectedDir = dir; |
2205 fDirection = (kRight_DirChange == dir) ? SkPath::kCW_Directi
on | 2210 fDirection = (kRight_DirChange == dir) ? SkPath::kCW_Directi
on |
2206 : SkPath::kCCW_Direct
ion; | 2211 : SkPath::kCCW_Direct
ion; |
2207 } else if (dir != fExpectedDir) { | 2212 } else if (dir != fExpectedDir) { |
2208 fConvexity = SkPath::kConcave_Convexity; | 2213 fConvexity = SkPath::kConcave_Convexity; |
2209 fDirection = SkPath::kUnknown_Direction; | 2214 fDirection = SkPath::kUnknown_Direction; |
2210 } | 2215 } |
2211 fLastVec = vec; | 2216 fLastVec = vec; |
2212 break; | 2217 break; |
2213 case kStraight_DirChange: | 2218 case kStraight_DirChange: |
2214 break; | 2219 break; |
2215 case kBackwards_DirChange: | 2220 case kBackwards_DirChange: |
| 2221 if (fIsCurve) { |
| 2222 fConvexity = SkPath::kConcave_Convexity; |
| 2223 fDirection = SkPath::kUnknown_Direction; |
| 2224 } |
2216 fLastVec = vec; | 2225 fLastVec = vec; |
2217 break; | 2226 break; |
2218 case kInvalid_DirChange: | 2227 case kInvalid_DirChange: |
2219 SkFAIL("Use of invalid direction change flag"); | 2228 SkFAIL("Use of invalid direction change flag"); |
2220 break; | 2229 break; |
2221 } | 2230 } |
2222 } | 2231 } |
2223 | 2232 |
2224 SkPoint fLastPt; | 2233 SkPoint fLastPt; |
2225 SkPoint fCurrPt; | 2234 SkPoint fCurrPt; |
2226 // fLastVec does not necessarily start at fLastPt. We only advance it when t
he cross product | 2235 // fLastVec does not necessarily start at fLastPt. We only advance it when t
he cross product |
2227 // value with the current vec is deemed to be of a significant value. | 2236 // value with the current vec is deemed to be of a significant value. |
2228 SkVector fLastVec, fFirstVec; | 2237 SkVector fLastVec, fFirstVec; |
2229 int fPtCount; // non-degenerate points | 2238 int fPtCount; // non-degenerate points |
2230 DirChange fExpectedDir; | 2239 DirChange fExpectedDir; |
2231 SkPath::Convexity fConvexity; | 2240 SkPath::Convexity fConvexity; |
2232 SkPath::Direction fDirection; | 2241 SkPath::Direction fDirection; |
2233 int fDx, fDy, fSx, fSy; | 2242 int fDx, fDy, fSx, fSy; |
2234 bool fIsFinite; | 2243 bool fIsFinite; |
| 2244 bool fIsCurve; |
2235 }; | 2245 }; |
2236 | 2246 |
2237 SkPath::Convexity SkPath::internalGetConvexity() const { | 2247 SkPath::Convexity SkPath::internalGetConvexity() const { |
2238 SkASSERT(kUnknown_Convexity == fConvexity); | 2248 SkASSERT(kUnknown_Convexity == fConvexity); |
2239 SkPoint pts[4]; | 2249 SkPoint pts[4]; |
2240 SkPath::Verb verb; | 2250 SkPath::Verb verb; |
2241 SkPath::Iter iter(*this, true); | 2251 SkPath::Iter iter(*this, true); |
2242 | 2252 |
2243 int contourCount = 0; | 2253 int contourCount = 0; |
2244 int count; | 2254 int count; |
2245 Convexicator state; | 2255 Convexicator state; |
2246 | 2256 |
2247 if (!isFinite()) { | 2257 if (!isFinite()) { |
2248 return kUnknown_Convexity; | 2258 return kUnknown_Convexity; |
2249 } | 2259 } |
2250 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | 2260 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
2251 switch (verb) { | 2261 switch (verb) { |
2252 case kMove_Verb: | 2262 case kMove_Verb: |
2253 if (++contourCount > 1) { | 2263 if (++contourCount > 1) { |
2254 fConvexity = kConcave_Convexity; | 2264 fConvexity = kConcave_Convexity; |
2255 return kConcave_Convexity; | 2265 return kConcave_Convexity; |
2256 } | 2266 } |
2257 pts[1] = pts[0]; | 2267 pts[1] = pts[0]; |
| 2268 // fall through |
| 2269 case kLine_Verb: |
2258 count = 1; | 2270 count = 1; |
| 2271 state.setCurve(false); |
2259 break; | 2272 break; |
2260 case kLine_Verb: count = 1; break; | 2273 case kQuad_Verb: |
2261 case kQuad_Verb: count = 2; break; | 2274 // fall through |
2262 case kConic_Verb: count = 2; break; | 2275 case kConic_Verb: |
2263 case kCubic_Verb: count = 3; break; | 2276 // fall through |
| 2277 case kCubic_Verb: |
| 2278 count = 2 + (kCubic_Verb == verb); |
| 2279 // As an additional enhancement, this could set curve true only |
| 2280 // if the curve is nonlinear |
| 2281 state.setCurve(true); |
| 2282 break; |
2264 case kClose_Verb: | 2283 case kClose_Verb: |
| 2284 state.setCurve(false); |
2265 state.close(); | 2285 state.close(); |
2266 count = 0; | 2286 count = 0; |
2267 break; | 2287 break; |
2268 default: | 2288 default: |
2269 SkDEBUGFAIL("bad verb"); | 2289 SkDEBUGFAIL("bad verb"); |
2270 fConvexity = kConcave_Convexity; | 2290 fConvexity = kConcave_Convexity; |
2271 return kConcave_Convexity; | 2291 return kConcave_Convexity; |
2272 } | 2292 } |
2273 | 2293 |
2274 for (int i = 1; i <= count; i++) { | 2294 for (int i = 1; i <= count; i++) { |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2792 switch (this->getFillType()) { | 2812 switch (this->getFillType()) { |
2793 case SkPath::kEvenOdd_FillType: | 2813 case SkPath::kEvenOdd_FillType: |
2794 case SkPath::kInverseEvenOdd_FillType: | 2814 case SkPath::kInverseEvenOdd_FillType: |
2795 w &= 1; | 2815 w &= 1; |
2796 break; | 2816 break; |
2797 default: | 2817 default: |
2798 break; | 2818 break; |
2799 } | 2819 } |
2800 return SkToBool(w); | 2820 return SkToBool(w); |
2801 } | 2821 } |
OLD | NEW |