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 | |
robertphillips
2015/11/19 22:27:28
Should this be 'setPathRef' ?
caryclark
2015/11/19 22:36:05
Done.
| |
117 void setPath(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 22 matching lines...) Expand all Loading... | |
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 = 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) { | |
robertphillips
2015/11/19 22:27:28
this->getRRect ?
caryclark
2015/11/19 22:36:05
Done.
| |
181 *rrect = 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 | |
414 SkPoint* getPoints() { | 457 SkPoint* getPoints() { |
415 SkDEBUGCODE(this->validate();) | 458 SkDEBUGCODE(this->validate();) |
416 fIsOval = false; | 459 fIsOval = false; |
460 fIsRRect = false; | |
reed1
2015/11/19 19:28:10
do we remember why calling this forces us to wack
caryclark
2015/11/19 20:49:05
This is only called by the editor.
Added a const f
| |
417 return fPoints; | 461 return fPoints; |
418 } | 462 } |
419 | 463 |
420 void callGenIDChangeListeners(); | 464 void callGenIDChangeListeners(); |
421 | 465 |
422 enum { | 466 enum { |
423 kMinSize = 256, | 467 kMinSize = 256, |
424 }; | 468 }; |
425 | 469 |
426 mutable SkRect fBounds; | 470 mutable SkRect fBounds; |
427 mutable uint8_t fBoundsIsDirty; | 471 mutable uint8_t fBoundsIsDirty; |
428 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid | 472 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid |
429 | 473 |
430 SkBool8 fIsOval; | 474 SkBool8 fIsOval; |
reed1
2015/11/19 19:28:10
we now have 5 bytes in a row, do we want to move a
caryclark
2015/11/19 20:49:05
Done.
| |
475 SkBool8 fIsRRect; | |
431 uint8_t fSegmentMask; | 476 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 |
448 friend class PathRefTest_Private; | 493 friend class PathRefTest_Private; |
494 friend class ForceIsRRect_Private; // unit test isRRect | |
449 typedef SkRefCnt INHERITED; | 495 typedef SkRefCnt INHERITED; |
450 }; | 496 }; |
451 | 497 |
452 #endif | 498 #endif |
OLD | NEW |