Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: include/core/SkPathRef.h

Issue 1461763004: add SkPath::isRRect (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: incorporated Rob's comments Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/core/SkPath.h ('k') | src/core/SkPath.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « include/core/SkPath.h ('k') | src/core/SkPath.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698