| 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 |
| 11 | 11 |
| 12 #include "SkMatrix.h" | 12 #include "SkMatrix.h" |
| 13 #include "SkPoint.h" | 13 #include "SkPoint.h" |
| 14 #include "SkRRect.h" |
| 14 #include "SkRect.h" | 15 #include "SkRect.h" |
| 15 #include "SkRefCnt.h" | 16 #include "SkRefCnt.h" |
| 16 #include "SkTDArray.h" | 17 #include "SkTDArray.h" |
| 17 #include <stddef.h> // ptrdiff_t | 18 #include <stddef.h> // ptrdiff_t |
| 18 | 19 |
| 19 class SkRBuffer; | 20 class SkRBuffer; |
| 20 class SkWBuffer; | 21 class SkWBuffer; |
| 21 | 22 |
| 22 /** | 23 /** |
| 23 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods | 24 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); | 94 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); |
| 94 } | 95 } |
| 95 | 96 |
| 96 /** | 97 /** |
| 97 * Gets the path ref that is wrapped in the Editor. | 98 * Gets the path ref that is wrapped in the Editor. |
| 98 */ | 99 */ |
| 99 SkPathRef* pathRef() { return fPathRef; } | 100 SkPathRef* pathRef() { return fPathRef; } |
| 100 | 101 |
| 101 void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); } | 102 void setIsOval(bool isOval) { fPathRef->setIsOval(isOval); } |
| 102 | 103 |
| 104 void setIsRRect(bool isRRect) { fPathRef->setIsRRect(isRRect); } |
| 105 |
| 103 void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } | 106 void setBounds(const SkRect& rect) { fPathRef->setBounds(rect); } |
| 104 | 107 |
| 105 private: | 108 private: |
| 106 SkPathRef* fPathRef; | 109 SkPathRef* fPathRef; |
| 107 }; | 110 }; |
| 108 | 111 |
| 112 class SK_API Iter { |
| 113 public: |
| 114 Iter(); |
| 115 Iter(const SkPathRef&); |
| 116 |
| 117 void setPathRef(const SkPathRef&); |
| 118 |
| 119 /** Return the next verb in this iteration of the path. When all |
| 120 segments have been visited, return kDone_Verb. |
| 121 |
| 122 @param pts The points representing the current verb and/or segment |
| 123 This must not be NULL. |
| 124 @return The verb for the current segment |
| 125 */ |
| 126 uint8_t next(SkPoint pts[4]); |
| 127 |
| 128 SkScalar conicWeight() const { return *fConicWeights; } |
| 129 |
| 130 private: |
| 131 const SkPoint* fPts; |
| 132 const uint8_t* fVerbs; |
| 133 const uint8_t* fVerbStop; |
| 134 const SkScalar* fConicWeights; |
| 135 }; |
| 136 |
| 109 public: | 137 public: |
| 110 /** | 138 /** |
| 111 * Gets a path ref with no verbs or points. | 139 * Gets a path ref with no verbs or points. |
| 112 */ | 140 */ |
| 113 static SkPathRef* CreateEmpty(); | 141 static SkPathRef* CreateEmpty(); |
| 114 | 142 |
| 115 /** | 143 /** |
| 116 * Returns true if all of the points in this path are finite, meaning there | 144 * Returns true if all of the points in this path are finite, meaning there |
| 117 * are no infinities and no NaNs. | 145 * are no infinities and no NaNs. |
| 118 */ | 146 */ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 135 * @param rect returns the bounding rect of this oval. It's a circle | 163 * @param rect returns the bounding rect of this oval. It's a circle |
| 136 * if the height and width are the same. | 164 * if the height and width are the same. |
| 137 * | 165 * |
| 138 * @return true if this path is an oval. | 166 * @return true if this path is an oval. |
| 139 * Tracking whether a path is an oval is considered an | 167 * Tracking whether a path is an oval is considered an |
| 140 * optimization for performance and so some paths that are in | 168 * optimization for performance and so some paths that are in |
| 141 * fact ovals can report false. | 169 * fact ovals can report false. |
| 142 */ | 170 */ |
| 143 bool isOval(SkRect* rect) const { | 171 bool isOval(SkRect* rect) const { |
| 144 if (fIsOval && rect) { | 172 if (fIsOval && rect) { |
| 145 *rect = getBounds(); | 173 *rect = this->getBounds(); |
| 146 } | 174 } |
| 147 | 175 |
| 148 return SkToBool(fIsOval); | 176 return SkToBool(fIsOval); |
| 149 } | 177 } |
| 150 | 178 |
| 179 bool isRRect(SkRRect* rrect) const { |
| 180 if (fIsRRect && rrect) { |
| 181 *rrect = this->getRRect(); |
| 182 } |
| 183 return SkToBool(fIsRRect); |
| 184 } |
| 185 |
| 186 |
| 151 bool hasComputedBounds() const { | 187 bool hasComputedBounds() const { |
| 152 return !fBoundsIsDirty; | 188 return !fBoundsIsDirty; |
| 153 } | 189 } |
| 154 | 190 |
| 155 /** Returns the bounds of the path's points. If the path contains 0 or 1 | 191 /** Returns the bounds of the path's points. If the path contains 0 or 1 |
| 156 points, the bounds is set to (0,0,0,0), and isEmpty() will return true. | 192 points, the bounds is set to (0,0,0,0), and isEmpty() will return true. |
| 157 Note: this bounds may be larger than the actual shape, since curves | 193 Note: this bounds may be larger than the actual shape, since curves |
| 158 do not extend as far as their control points. | 194 do not extend as far as their control points. |
| 159 */ | 195 */ |
| 160 const SkRect& getBounds() const { | 196 const SkRect& getBounds() const { |
| 161 if (fBoundsIsDirty) { | 197 if (fBoundsIsDirty) { |
| 162 this->computeBounds(); | 198 this->computeBounds(); |
| 163 } | 199 } |
| 164 return fBounds; | 200 return fBounds; |
| 165 } | 201 } |
| 166 | 202 |
| 203 SkRRect getRRect() const; |
| 204 |
| 167 /** | 205 /** |
| 168 * Transforms a path ref by a matrix, allocating a new one only if necessary
. | 206 * Transforms a path ref by a matrix, allocating a new one only if necessary
. |
| 169 */ | 207 */ |
| 170 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, | 208 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, |
| 171 const SkPathRef& src, | 209 const SkPathRef& src, |
| 172 const SkMatrix& matrix); | 210 const SkMatrix& matrix); |
| 173 | 211 |
| 174 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer); | 212 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer); |
| 175 | 213 |
| 176 /** | 214 /** |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 virtual ~GenIDChangeListener() {} | 281 virtual ~GenIDChangeListener() {} |
| 244 virtual void onChange() = 0; | 282 virtual void onChange() = 0; |
| 245 }; | 283 }; |
| 246 | 284 |
| 247 void addGenIDChangeListener(GenIDChangeListener* listener); | 285 void addGenIDChangeListener(GenIDChangeListener* listener); |
| 248 | 286 |
| 249 SkDEBUGCODE(void validate() const;) | 287 SkDEBUGCODE(void validate() const;) |
| 250 | 288 |
| 251 private: | 289 private: |
| 252 enum SerializationOffsets { | 290 enum SerializationOffsets { |
| 291 kIsRRect_SerializationShift = 26, // requires 1 bit |
| 253 kIsFinite_SerializationShift = 25, // requires 1 bit | 292 kIsFinite_SerializationShift = 25, // requires 1 bit |
| 254 kIsOval_SerializationShift = 24, // requires 1 bit | 293 kIsOval_SerializationShift = 24, // requires 1 bit |
| 255 kSegmentMask_SerializationShift = 0 // requires 4 bits | 294 kSegmentMask_SerializationShift = 0 // requires 4 bits |
| 256 }; | 295 }; |
| 257 | 296 |
| 258 SkPathRef() { | 297 SkPathRef() { |
| 259 fBoundsIsDirty = true; // this also invalidates fIsFinite | 298 fBoundsIsDirty = true; // this also invalidates fIsFinite |
| 260 fPointCnt = 0; | 299 fPointCnt = 0; |
| 261 fVerbCnt = 0; | 300 fVerbCnt = 0; |
| 262 fVerbs = NULL; | 301 fVerbs = NULL; |
| 263 fPoints = NULL; | 302 fPoints = NULL; |
| 264 fFreeSpace = 0; | 303 fFreeSpace = 0; |
| 265 fGenerationID = kEmptyGenID; | 304 fGenerationID = kEmptyGenID; |
| 266 fSegmentMask = 0; | 305 fSegmentMask = 0; |
| 267 fIsOval = false; | 306 fIsOval = false; |
| 307 fIsRRect = false; |
| 268 SkDEBUGCODE(fEditorsAttached = 0;) | 308 SkDEBUGCODE(fEditorsAttached = 0;) |
| 269 SkDEBUGCODE(this->validate();) | 309 SkDEBUGCODE(this->validate();) |
| 270 } | 310 } |
| 271 | 311 |
| 272 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); | 312 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); |
| 273 | 313 |
| 274 // Return true if the computed bounds are finite. | 314 // Return true if the computed bounds are finite. |
| 275 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { | 315 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { |
| 276 return bounds->setBoundsCheck(ref.points(), ref.countPoints()); | 316 return bounds->setBoundsCheck(ref.points(), ref.countPoints()); |
| 277 } | 317 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 305 /** Resets the path ref with verbCount verbs and pointCount points, all unin
itialized. Also | 345 /** Resets the path ref with verbCount verbs and pointCount points, all unin
itialized. Also |
| 306 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ | 346 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ |
| 307 void resetToSize(int verbCount, int pointCount, int conicCount, | 347 void resetToSize(int verbCount, int pointCount, int conicCount, |
| 308 int reserveVerbs = 0, int reservePoints = 0) { | 348 int reserveVerbs = 0, int reservePoints = 0) { |
| 309 SkDEBUGCODE(this->validate();) | 349 SkDEBUGCODE(this->validate();) |
| 310 fBoundsIsDirty = true; // this also invalidates fIsFinite | 350 fBoundsIsDirty = true; // this also invalidates fIsFinite |
| 311 fGenerationID = 0; | 351 fGenerationID = 0; |
| 312 | 352 |
| 313 fSegmentMask = 0; | 353 fSegmentMask = 0; |
| 314 fIsOval = false; | 354 fIsOval = false; |
| 355 fIsRRect = false; |
| 315 | 356 |
| 316 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo
unt; | 357 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo
unt; |
| 317 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r
eservePoints; | 358 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r
eservePoints; |
| 318 size_t minSize = newSize + newReserve; | 359 size_t minSize = newSize + newReserve; |
| 319 | 360 |
| 320 ptrdiff_t sizeDelta = this->currSize() - minSize; | 361 ptrdiff_t sizeDelta = this->currSize() - minSize; |
| 321 | 362 |
| 322 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { | 363 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { |
| 323 sk_free(fPoints); | 364 sk_free(fPoints); |
| 324 fPoints = NULL; | 365 fPoints = NULL; |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f
Points); | 445 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f
Points); |
| 405 } | 446 } |
| 406 | 447 |
| 407 /** | 448 /** |
| 408 * Called the first time someone calls CreateEmpty to actually create the si
ngleton. | 449 * Called the first time someone calls CreateEmpty to actually create the si
ngleton. |
| 409 */ | 450 */ |
| 410 friend SkPathRef* sk_create_empty_pathref(); | 451 friend SkPathRef* sk_create_empty_pathref(); |
| 411 | 452 |
| 412 void setIsOval(bool isOval) { fIsOval = isOval; } | 453 void setIsOval(bool isOval) { fIsOval = isOval; } |
| 413 | 454 |
| 455 void setIsRRect(bool isRRect) { fIsRRect = isRRect; } |
| 456 |
| 457 // called only by the editor. Note that this is not a const function. |
| 414 SkPoint* getPoints() { | 458 SkPoint* getPoints() { |
| 415 SkDEBUGCODE(this->validate();) | 459 SkDEBUGCODE(this->validate();) |
| 416 fIsOval = false; | 460 fIsOval = false; |
| 461 fIsRRect = false; |
| 417 return fPoints; | 462 return fPoints; |
| 418 } | 463 } |
| 419 | 464 |
| 465 const SkPoint* getPoints() const { |
| 466 SkDEBUGCODE(this->validate();) |
| 467 return fPoints; |
| 468 } |
| 469 |
| 420 void callGenIDChangeListeners(); | 470 void callGenIDChangeListeners(); |
| 421 | 471 |
| 422 enum { | 472 enum { |
| 423 kMinSize = 256, | 473 kMinSize = 256, |
| 424 }; | 474 }; |
| 425 | 475 |
| 426 mutable SkRect fBounds; | 476 mutable SkRect fBounds; |
| 427 mutable uint8_t fBoundsIsDirty; | |
| 428 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid | |
| 429 | |
| 430 SkBool8 fIsOval; | |
| 431 uint8_t fSegmentMask; | |
| 432 | 477 |
| 433 SkPoint* fPoints; // points to begining of the allocation | 478 SkPoint* fPoints; // points to begining of the allocation |
| 434 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) | 479 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) |
| 435 int fVerbCnt; | 480 int fVerbCnt; |
| 436 int fPointCnt; | 481 int fPointCnt; |
| 437 size_t fFreeSpace; // redundant but saves computation | 482 size_t fFreeSpace; // redundant but saves computation |
| 438 SkTDArray<SkScalar> fConicWeights; | 483 SkTDArray<SkScalar> fConicWeights; |
| 439 | 484 |
| 440 enum { | 485 enum { |
| 441 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. | 486 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. |
| 442 }; | 487 }; |
| 443 mutable uint32_t fGenerationID; | 488 mutable uint32_t fGenerationID; |
| 444 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. | 489 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. |
| 445 | 490 |
| 446 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d | 491 SkTDArray<GenIDChangeListener*> fGenIDChangeListeners; // pointers are owne
d |
| 447 | 492 |
| 493 mutable uint8_t fBoundsIsDirty; |
| 494 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid |
| 495 |
| 496 SkBool8 fIsOval; |
| 497 SkBool8 fIsRRect; |
| 498 uint8_t fSegmentMask; |
| 499 |
| 448 friend class PathRefTest_Private; | 500 friend class PathRefTest_Private; |
| 501 friend class ForceIsRRect_Private; // unit test isRRect |
| 449 typedef SkRefCnt INHERITED; | 502 typedef SkRefCnt INHERITED; |
| 450 }; | 503 }; |
| 451 | 504 |
| 452 #endif | 505 #endif |
| OLD | NEW |