| 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 "SkRect.h" | 14 #include "SkRect.h" |
| 15 #include "SkRefCnt.h" | 15 #include "SkRefCnt.h" |
| 16 #include "SkTDArray.h" | 16 #include "SkTDArray.h" |
| 17 #include <stddef.h> // ptrdiff_t | 17 #include <stddef.h> // ptrdiff_t |
| 18 | 18 |
| 19 class SkRBuffer; | 19 class SkRBuffer; |
| 20 class SkWBuffer; | 20 class SkWBuffer; |
| 21 | 21 |
| 22 /** | 22 /** |
| 23 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods | 23 * Holds the path verbs and points. It is versioned by a generation ID. None of
its public methods |
| 24 * modify the contents. To modify or append to the verbs/points wrap the SkPathR
ef in an | 24 * modify the contents. To modify or append to the verbs/points wrap the SkPathR
ef in an |
| 25 * SkPathRef::Editor object. Installing the editor resets the generation ID. It
also performs | 25 * SkPathRef::Editor object. Installing the editor resets the generation ID. It
also performs |
| 26 * copy-on-write if the SkPathRef is shared by multipls SkPaths. The caller pass
es the Editor's | 26 * copy-on-write if the SkPathRef is shared by multiple SkPaths. The caller pass
es the Editor's |
| 27 * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef
after the editor's | 27 * constructor a SkAutoTUnref, which may be updated to point to a new SkPathRef
after the editor's |
| 28 * constructor returns. | 28 * constructor returns. |
| 29 * | 29 * |
| 30 * The points and verbs are stored in a single allocation. The points are at the
begining of the | 30 * The points and verbs are stored in a single allocation. The points are at the
begining of the |
| 31 * allocation while the verbs are stored at end of the allocation, in reverse or
der. Thus the points | 31 * allocation while the verbs are stored at end of the allocation, in reverse or
der. Thus the points |
| 32 * and verbs both grow into the middle of the allocation until the meet. To acce
ss verb i in the | 32 * and verbs both grow into the middle of the allocation until the meet. To acce
ss verb i in the |
| 33 * verb array use ref.verbs()[~i] (because verbs() returns a pointer just beyond
the first | 33 * verb array use ref.verbs()[~i] (because verbs() returns a pointer just beyond
the first |
| 34 * logical verb or the last verb in memory). | 34 * logical verb or the last verb in memory). |
| 35 */ | 35 */ |
| 36 | 36 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 * uninitialized. | 93 * uninitialized. |
| 94 */ | 94 */ |
| 95 void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) { | 95 void resetToSize(int newVerbCnt, int newPointCnt, int newConicCount) { |
| 96 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); | 96 fPathRef->resetToSize(newVerbCnt, newPointCnt, newConicCount); |
| 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); } |
| 104 |
| 103 private: | 105 private: |
| 104 SkPathRef* fPathRef; | 106 SkPathRef* fPathRef; |
| 105 }; | 107 }; |
| 106 | 108 |
| 107 public: | 109 public: |
| 108 /** | 110 /** |
| 109 * Gets a path ref with no verbs or points. | 111 * Gets a path ref with no verbs or points. |
| 110 */ | 112 */ |
| 111 static SkPathRef* CreateEmpty(); | 113 static SkPathRef* CreateEmpty(); |
| 112 | 114 |
| 113 /** | 115 /** |
| 114 * Returns true if all of the points in this path are finite, meaning there | 116 * Returns true if all of the points in this path are finite, meaning there |
| 115 * are no infinities and no NaNs. | 117 * are no infinities and no NaNs. |
| 116 */ | 118 */ |
| 117 bool isFinite() const { | 119 bool isFinite() const { |
| 118 if (fBoundsIsDirty) { | 120 if (fBoundsIsDirty) { |
| 119 this->computeBounds(); | 121 this->computeBounds(); |
| 120 } | 122 } |
| 121 return SkToBool(fIsFinite); | 123 return SkToBool(fIsFinite); |
| 122 } | 124 } |
| 123 | 125 |
| 126 /** Returns true if the path is an oval. |
| 127 * |
| 128 * @param rect returns the bounding rect of this oval. It's a circle |
| 129 * if the height and width are the same. |
| 130 * |
| 131 * @return true if this path is an oval. |
| 132 * Tracking whether a path is an oval is considered an |
| 133 * optimization for performance and so some paths that are in |
| 134 * fact ovals can report false. |
| 135 */ |
| 136 bool isOval(SkRect* rect) const { |
| 137 if (fIsOval && NULL != rect) { |
| 138 *rect = getBounds(); |
| 139 } |
| 140 |
| 141 return SkToBool(fIsOval); |
| 142 } |
| 143 |
| 124 bool hasComputedBounds() const { | 144 bool hasComputedBounds() const { |
| 125 return !fBoundsIsDirty; | 145 return !fBoundsIsDirty; |
| 126 } | 146 } |
| 127 | 147 |
| 128 /** Returns the bounds of the path's points. If the path contains 0 or 1 | 148 /** Returns the bounds of the path's points. If the path contains 0 or 1 |
| 129 points, the bounds is set to (0,0,0,0), and isEmpty() will return true. | 149 points, the bounds is set to (0,0,0,0), and isEmpty() will return true. |
| 130 Note: this bounds may be larger than the actual shape, since curves | 150 Note: this bounds may be larger than the actual shape, since curves |
| 131 do not extend as far as their control points. | 151 do not extend as far as their control points. |
| 132 */ | 152 */ |
| 133 const SkRect& getBounds() const { | 153 const SkRect& getBounds() const { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 145 } | 165 } |
| 146 | 166 |
| 147 /** | 167 /** |
| 148 * Transforms a path ref by a matrix, allocating a new one only if necessary
. | 168 * Transforms a path ref by a matrix, allocating a new one only if necessary
. |
| 149 */ | 169 */ |
| 150 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, | 170 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, |
| 151 const SkPathRef& src, | 171 const SkPathRef& src, |
| 152 const SkMatrix& matrix); | 172 const SkMatrix& matrix); |
| 153 | 173 |
| 154 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer | 174 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer |
| 155 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO
O | 175 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V16_AND_ALL_OTHER_INSTANCES_TO
O |
| 156 , bool newFormat, int32_t oldPacked | 176 , bool newFormat, int32_t oldPacked |
| 157 #endif | 177 #endif |
| 158 ); | 178 ); |
| 159 | 179 |
| 160 /** | 180 /** |
| 161 * Rollsback a path ref to zero verbs and points with the assumption that th
e path ref will be | 181 * Rollsback a path ref to zero verbs and points with the assumption that th
e path ref will be |
| 162 * repopulated with approximately the same number of verbs and points. A new
path ref is created | 182 * repopulated with approximately the same number of verbs and points. A new
path ref is created |
| 163 * only if necessary. | 183 * only if necessary. |
| 164 */ | 184 */ |
| 165 static void Rewind(SkAutoTUnref<SkPathRef>* pathRef); | 185 static void Rewind(SkAutoTUnref<SkPathRef>* pathRef); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 /** | 250 /** |
| 231 * Gets an ID that uniquely identifies the contents of the path ref. If two
path refs have the | 251 * Gets an ID that uniquely identifies the contents of the path ref. If two
path refs have the |
| 232 * same ID then they have the same verbs and points. However, two path refs
may have the same | 252 * same ID then they have the same verbs and points. However, two path refs
may have the same |
| 233 * contents but different genIDs. | 253 * contents but different genIDs. |
| 234 */ | 254 */ |
| 235 uint32_t genID() const; | 255 uint32_t genID() const; |
| 236 | 256 |
| 237 private: | 257 private: |
| 238 enum SerializationOffsets { | 258 enum SerializationOffsets { |
| 239 kIsFinite_SerializationShift = 25, // requires 1 bit | 259 kIsFinite_SerializationShift = 25, // requires 1 bit |
| 260 kIsOval_SerializationShift = 24, // requires 1 bit |
| 240 }; | 261 }; |
| 241 | 262 |
| 242 SkPathRef() { | 263 SkPathRef() { |
| 243 fBoundsIsDirty = true; // this also invalidates fIsFinite | 264 fBoundsIsDirty = true; // this also invalidates fIsFinite |
| 244 fPointCnt = 0; | 265 fPointCnt = 0; |
| 245 fVerbCnt = 0; | 266 fVerbCnt = 0; |
| 246 fVerbs = NULL; | 267 fVerbs = NULL; |
| 247 fPoints = NULL; | 268 fPoints = NULL; |
| 248 fFreeSpace = 0; | 269 fFreeSpace = 0; |
| 249 fGenerationID = kEmptyGenID; | 270 fGenerationID = kEmptyGenID; |
| 271 fIsOval = false; |
| 250 SkDEBUGCODE(fEditorsAttached = 0;) | 272 SkDEBUGCODE(fEditorsAttached = 0;) |
| 251 SkDEBUGCODE(this->validate();) | 273 SkDEBUGCODE(this->validate();) |
| 252 } | 274 } |
| 253 | 275 |
| 254 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); | 276 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe
servePoints); |
| 255 | 277 |
| 256 // Return true if the computed bounds are finite. | 278 // Return true if the computed bounds are finite. |
| 257 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { | 279 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) { |
| 258 int count = ref.countPoints(); | 280 int count = ref.countPoints(); |
| 259 if (count <= 1) { // we ignore just 1 point (moveto) | 281 if (count <= 1) { // we ignore just 1 point (moveto) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 282 } | 304 } |
| 283 | 305 |
| 284 /** Resets the path ref with verbCount verbs and pointCount points, all unin
itialized. Also | 306 /** Resets the path ref with verbCount verbs and pointCount points, all unin
itialized. Also |
| 285 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ | 307 * allocates space for reserveVerb additional verbs and reservePoints addit
ional points.*/ |
| 286 void resetToSize(int verbCount, int pointCount, int conicCount, | 308 void resetToSize(int verbCount, int pointCount, int conicCount, |
| 287 int reserveVerbs = 0, int reservePoints = 0) { | 309 int reserveVerbs = 0, int reservePoints = 0) { |
| 288 SkDEBUGCODE(this->validate();) | 310 SkDEBUGCODE(this->validate();) |
| 289 fBoundsIsDirty = true; // this also invalidates fIsFinite | 311 fBoundsIsDirty = true; // this also invalidates fIsFinite |
| 290 fGenerationID = 0; | 312 fGenerationID = 0; |
| 291 | 313 |
| 314 fIsOval = false; |
| 315 |
| 292 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo
unt; | 316 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo
unt; |
| 293 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r
eservePoints; | 317 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r
eservePoints; |
| 294 size_t minSize = newSize + newReserve; | 318 size_t minSize = newSize + newReserve; |
| 295 | 319 |
| 296 ptrdiff_t sizeDelta = this->currSize() - minSize; | 320 ptrdiff_t sizeDelta = this->currSize() - minSize; |
| 297 | 321 |
| 298 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { | 322 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { |
| 299 sk_free(fPoints); | 323 sk_free(fPoints); |
| 300 fPoints = NULL; | 324 fPoints = NULL; |
| 301 fVerbs = NULL; | 325 fVerbs = NULL; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f
Points); | 411 return reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t>(f
Points); |
| 388 } | 412 } |
| 389 | 413 |
| 390 SkDEBUGCODE(void validate() const;) | 414 SkDEBUGCODE(void validate() const;) |
| 391 | 415 |
| 392 /** | 416 /** |
| 393 * Called the first time someone calls CreateEmpty to actually create the si
ngleton. | 417 * Called the first time someone calls CreateEmpty to actually create the si
ngleton. |
| 394 */ | 418 */ |
| 395 static void CreateEmptyImpl(SkPathRef** empty); | 419 static void CreateEmptyImpl(SkPathRef** empty); |
| 396 | 420 |
| 421 void setIsOval(bool isOval) { fIsOval = isOval; } |
| 422 |
| 397 enum { | 423 enum { |
| 398 kMinSize = 256, | 424 kMinSize = 256, |
| 399 }; | 425 }; |
| 400 | 426 |
| 401 mutable SkRect fBounds; | 427 mutable SkRect fBounds; |
| 402 mutable uint8_t fBoundsIsDirty; | 428 mutable uint8_t fBoundsIsDirty; |
| 403 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid | 429 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid |
| 430 mutable SkBool8 fIsOval; |
| 404 | 431 |
| 405 SkPoint* fPoints; // points to begining of the allocation | 432 SkPoint* fPoints; // points to begining of the allocation |
| 406 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) | 433 uint8_t* fVerbs; // points just past the end of the allocation (v
erbs grow backwards) |
| 407 int fVerbCnt; | 434 int fVerbCnt; |
| 408 int fPointCnt; | 435 int fPointCnt; |
| 409 size_t fFreeSpace; // redundant but saves computation | 436 size_t fFreeSpace; // redundant but saves computation |
| 410 SkTDArray<SkScalar> fConicWeights; | 437 SkTDArray<SkScalar> fConicWeights; |
| 411 | 438 |
| 412 enum { | 439 enum { |
| 413 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. | 440 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer
o verbs. |
| 414 }; | 441 }; |
| 415 mutable uint32_t fGenerationID; | 442 mutable uint32_t fGenerationID; |
| 416 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. | 443 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use
at any time. |
| 417 | 444 |
| 418 typedef SkRefCnt INHERITED; | 445 typedef SkRefCnt INHERITED; |
| 419 }; | 446 }; |
| 420 | 447 |
| 421 #endif | 448 #endif |
| OLD | NEW |