OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2012 Google Inc. | 3 * Copyright 2012 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #ifndef SkPathRef_DEFINED | 9 #ifndef SkPathRef_DEFINED |
10 #define SkPathRef_DEFINED | 10 #define SkPathRef_DEFINED |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 */ | 93 */ |
94 void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) { | 94 void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) { |
95 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); | 95 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); |
96 } | 96 } |
97 | 97 |
98 /** | 98 /** |
99 * Gets the path ref that is wrapped in the Editor. | 99 * Gets the path ref that is wrapped in the Editor. |
100 */ | 100 */ |
101 SkPathRef* pathRef() { return fPathRef; } | 101 SkPathRef* pathRef() { return fPathRef; } |
102 | 102 |
103 void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); } | 103 void setIsOval(bool isOval, bool isCCW, unsigned start) { |
| 104 fPathRef->setIsOval(isOval, isCCW, start); |
| 105 } |
104 | 106 |
105 void setIsRRect(bool isRRect) { fPathRef->setIsRRect(isRRect); } | 107 void setIsRRect(bool isRRect, bool isCCW, unsigned start) { |
| 108 fPathRef->setIsRRect(isRRect, isCCW, start); |
| 109 } |
106 | 110 |
107 void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } | 111 void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } |
108 | 112 |
109 private: | 113 private: |
110 SkPathRef* fPathRef; | 114 SkPathRef* fPathRef; |
111 }; | 115 }; |
112 | 116 |
113 class SK_API Iter { | 117 class SK_API Iter { |
114 public: | 118 public: |
115 Iter(); | 119 Iter(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 * Returns a mask, where each bit corresponding to a SegmentMask is | 161 * Returns a mask, where each bit corresponding to a SegmentMask is |
158 * set if the path contains 1 or more segments of that type. | 162 * set if the path contains 1 or more segments of that type. |
159 * Returns 0 for an empty path (no segments). | 163 * Returns 0 for an empty path (no segments). |
160 */ | 164 */ |
161 uint32_t getSegmentMasks() const { return fSegmentMask; } | 165 uint32_t getSegmentMasks() const { return fSegmentMask; } |
162 | 166 |
163 /** Returns true if the path is an oval. | 167 /** Returns true if the path is an oval. |
164 * | 168 * |
165 * @param rect returns the bounding rect of this oval. It's a circle | 169 * @param rect returns the bounding rect of this oval. It's a circle |
166 * if the height and width are the same. | 170 * if the height and width are the same. |
| 171 * @param isCCW is the oval CCW (or CW if false). |
| 172 * @param start indicates where the contour starts on the oval (see |
| 173 * SkPath::addOval for intepretation of the index). |
167 * | 174 * |
168 * @return true if this path is an oval. | 175 * @return true if this path is an oval. |
169 * Tracking whether a path is an oval is considered an | 176 * Tracking whether a path is an oval is considered an |
170 * optimization for performance and so some paths that are in | 177 * optimization for performance and so some paths that are in |
171 * fact ovals can report false. | 178 * fact ovals can report false. |
172 */ | 179 */ |
173 bool isOval(SkRect* rect) const { | 180 bool isOval(SkRect* rect, bool* isCCW, unsigned* start) const { |
174 if (fIsOval && rect) { | 181 if (fIsOval) { |
175 *rect = this->getBounds(); | 182 if (rect) { |
| 183 *rect = this->getBounds(); |
| 184 } |
| 185 if (isCCW) { |
| 186 *isCCW = SkToBool(fRRectOrOvalIsCCW); |
| 187 } |
| 188 if (start) { |
| 189 *start = fRRectOrOvalStartIdx; |
| 190 } |
176 } | 191 } |
177 | 192 |
178 return SkToBool(fIsOval); | 193 return SkToBool(fIsOval); |
179 } | 194 } |
180 | 195 |
181 bool isRRect(SkRRect* rrect) const { | 196 bool isRRect(SkRRect* rrect, bool* isCCW, unsigned* start) const { |
182 if (fIsRRect && rrect) { | 197 if (fIsRRect) { |
183 *rrect = this->getRRect(); | 198 if (rrect) { |
| 199 *rrect = this->getRRect(); |
| 200 } |
| 201 if (isCCW) { |
| 202 *isCCW = SkToBool(fRRectOrOvalIsCCW); |
| 203 } |
| 204 if (start) { |
| 205 *start = fRRectOrOvalStartIdx; |
| 206 } |
184 } | 207 } |
185 return SkToBool(fIsRRect); | 208 return SkToBool(fIsRRect); |
186 } | 209 } |
187 | 210 |
188 | 211 |
189 bool hasComputedBounds() const { | 212 bool hasComputedBounds() const { |
190 return !fBoundsIsDirty; | 213 return !fBoundsIsDirty; |
191 } | 214 } |
192 | 215 |
193 /** Returns the bounds of the path's points. If the path contains 0 or 1 | 216 /** Returns the bounds of the path's points. If the path contains 0 or 1 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
285 virtual ~GenIDChangeListener() {} | 308 virtual ~GenIDChangeListener() {} |
286 virtual void onChange() = 0; | 309 virtual void onChange() = 0; |
287 }; | 310 }; |
288 | 311 |
289 void addGenIDChangeListener(GenIDChangeListener* listener); | 312 void addGenIDChangeListener(GenIDChangeListener* listener); |
290 | 313 |
291 SkDEBUGCODE(void validate() const;) | 314 SkDEBUGCODE(void validate() const;) |
292 | 315 |
293 private: | 316 private: |
294 enum SerializationOffsets { | 317 enum SerializationOffsets { |
295 kIsRRect_SerializationShift = 26, // requires 1 bit | 318 kRRectOrOvalStartIdx_SerializationShift = 28, // requires 3 bits |
296 kIsFinite_SerializationShift = 25, // requires 1 bit | 319 kRRectOrOvalIsCCW_SerializationShift = 27, // requires 1 bit |
297 kIsOval_SerializationShift = 24, // requires 1 bit | 320 kIsRRect_SerializationShift = 26, // requires 1 bit |
298 kSegmentMask_SerializationShift = 0 // requires 4 bits | 321 kIsFinite_SerializationShift = 25, // requires 1 bit |
| 322 kIsOval_SerializationShift = 24, // requires 1 bit |
| 323 kSegmentMask_SerializationShift = 0 // requires 4 bits |
299 }; | 324 }; |
300 | 325 |
301 SkPathRef() { | 326 SkPathRef() { |
302 fBoundsIsDirty = true; // this also invalidates fIsFinite | 327 fBoundsIsDirty = true; // this also invalidates fIsFinite |
303 fPointCnt = 0; | 328 fPointCnt = 0; |
304 fVerbCnt = 0; | 329 fVerbCnt = 0; |
305 fVerbs = NULL; | 330 fVerbs = NULL; |
306 fPoints = NULL; | 331 fPoints = NULL; |
307 fFreeSpace = 0; | 332 fFreeSpace = 0; |
308 fGenerationID = kEmptyGenID; | 333 fGenerationID = kEmptyGenID; |
309 fSegmentMask = 0; | 334 fSegmentMask = 0; |
310 fIsOval = false; | 335 fIsOval = false; |
311 fIsRRect = false; | 336 fIsRRect = false; |
| 337 // The next two values don't matter unless fIsOval or fIsRRect are true. |
| 338 SkDEBUGCODE(fRRectOrOvalIsCCW = false); |
| 339 SkDEBUGCODE(fRRectOrOvalStartIdx = 0xAC); |
312 SkDEBUGCODE(fEditorsAttached = 0;) | 340 SkDEBUGCODE(fEditorsAttached = 0;) |
313 SkDEBUGCODE(this->validate();) | 341 SkDEBUGCODE(this->validate();) |
314 } | 342 } |
315 | 343 |
316 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); | 344 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); |
317 | 345 |
318 // Return true if the computed bounds are finite. | 346 // Return true if the computed bounds are finite. |
319 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { | 347 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { |
320 return bounds->setBoundsCheck(ref.points(), ref.countPoints()); | 348 return bounds->setBoundsCheck(ref.points(), ref.countPoints()); |
321 } | 349 } |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
447 */ | 475 */ |
448 size_t currSize() const { | 476 size_t currSize() const { |
449 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f
Points); | 477 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f
Points); |
450 } | 478 } |
451 | 479 |
452 /** | 480 /** |
453 * Called the first time someone calls CreateEmpty to actually create the si
ngleton. | 481 * Called the first time someone calls CreateEmpty to actually create the si
ngleton. |
454 */ | 482 */ |
455 friend SkPathRef* sk_create_empty_pathref(); | 483 friend SkPathRef* sk_create_empty_pathref(); |
456 | 484 |
457 void setIsOval(bool isOval) { fIsOval = isOval; } | 485 void setIsOval(bool isOval, bool isCCW, unsigned start) { |
| 486 fIsOval = isOval; |
| 487 fRRectOrOvalIsCCW = isCCW; |
| 488 fRRectOrOvalStartIdx = start; |
| 489 } |
458 | 490 |
459 void setIsRRect(bool isRRect) { fIsRRect = isRRect; } | 491 void setIsRRect(bool isRRect, bool isCCW, unsigned start) { |
| 492 fIsRRect = isRRect; |
| 493 fRRectOrOvalIsCCW = isCCW; |
| 494 fRRectOrOvalStartIdx = start; |
| 495 } |
460 | 496 |
461 // called only by the editor. Note that this is not a const function. | 497 // called only by the editor. Note that this is not a const function. |
462 SkPoint* getPoints() { | 498 SkPoint* getPoints() { |
463 SkDEBUGCODE(this->validate();) | 499 SkDEBUGCODE(this->validate();) |
464 fIsOval = false; | 500 fIsOval = false; |
465 fIsRRect = false; | 501 fIsRRect = false; |
466 return fPoints; | 502 return fPoints; |
467 } | 503 } |
468 | 504 |
469 const SkPoint* getPoints() const { | 505 const SkPoint* getPoints() const { |
(...skipping 22 matching lines...) Expand all Loading... |
492 mutable uint32_t fGenerationID; | 528 mutable uint32_t fGenerationID; |
493 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. | 529 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. |
494 | 530 |
495 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d | 531 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d |
496 | 532 |
497 mutable uint8_t fBoundsIsDirty; | 533 mutable uint8_t fBoundsIsDirty; |
498 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid | 534 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid |
499 | 535 |
500 SkBool8 fIsOval; | 536 SkBool8 fIsOval; |
501 SkBool8 fIsRRect; | 537 SkBool8 fIsRRect; |
| 538 // Both the circle and rrect special cases have a notion of direction and st
arting point |
| 539 // The next two variables store that information for either. |
| 540 SkBool8 fRRectOrOvalIsCCW; |
| 541 uint8_t fRRectOrOvalStartIdx; |
502 uint8_t fSegmentMask; | 542 uint8_t fSegmentMask; |
503 | 543 |
504 friend class PathRefTest_Private; | 544 friend class PathRefTest_Private; |
505 friend class ForceIsRRect_Private; // unit test isRRect | 545 friend class ForceIsRRect_Private; // unit test isRRect |
506 typedef SkRefCnt INHERITED; | 546 typedef SkRefCnt INHERITED; |
507 }; | 547 }; |
508 | 548 |
509 #endif | 549 #endif |
OLD | NEW |