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

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

Issue 24350006: Move bound and isFinite into pathref (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: yet more cleanup Created 7 years, 3 months 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 | Annotate | Revision Log
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
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 */ 122 */
123 static SkPathRef* CreateEmpty() { 123 static SkPathRef* CreateEmpty() {
124 static SkPathRef* gEmptyPathRef; 124 static SkPathRef* gEmptyPathRef;
125 if (!gEmptyPathRef) { 125 if (!gEmptyPathRef) {
126 gEmptyPathRef = SkNEW(SkPathRef); // leak! 126 gEmptyPathRef = SkNEW(SkPathRef); // leak!
127 } 127 }
128 return SkRef(gEmptyPathRef); 128 return SkRef(gEmptyPathRef);
129 } 129 }
130 130
131 /** 131 /**
132 * Returns true if all of the points in this path are finite, meaning there
133 * are no infinities and no NaNs.
134 */
135 bool isFinite() const {
136 if (fBoundsIsDirty) {
137 this->computeBounds();
138 }
139 return SkToBool(fIsFinite);
140 }
141
142 bool hasComputedBounds() const {
143 return !fBoundsIsDirty;
144 }
145
146 /** Returns the bounds of the path's points. If the path contains 0 or 1
147 points, the bounds is set to (0,0,0,0), and isEmpty() will return true.
148 Note: this bounds may be larger than the actual shape, since curves
149 do not extend as far as their control points.
150 */
151 const SkRect& getBounds() const {
152 if (fBoundsIsDirty) {
153 this->computeBounds();
154 }
155 return fBounds;
156 }
157
158 void setBounds(const SkRect& rect) {
159 SkASSERT(rect.fLeft <= rect.fRight && rect.fTop <= rect.fBottom);
160 fBounds = rect;
161 fBoundsIsDirty = false;
162 fIsFinite = fBounds.isFinite();
163 }
164
165 /**
132 * Transforms a path ref by a matrix, allocating a new one only if necessary . 166 * Transforms a path ref by a matrix, allocating a new one only if necessary .
133 */ 167 */
134 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst, 168 static void CreateTransformedCopy(SkAutoTUnref<SkPathRef>* dst,
135 const SkPathRef& src, 169 const SkPathRef& src,
136 const SkMatrix& matrix) { 170 const SkMatrix& matrix) {
137 src.validate(); 171 src.validate();
138 if (matrix.isIdentity()) { 172 if (matrix.isIdentity()) {
139 if (*dst != &src) { 173 if (*dst != &src) {
140 src.ref(); 174 src.ref();
141 dst->reset(const_cast<SkPathRef*>(&src)); 175 dst->reset(const_cast<SkPathRef*>(&src));
142 (*dst)->validate(); 176 (*dst)->validate();
143 } 177 }
144 return; 178 return;
145 } 179 }
180
146 bool dstUnique = (*dst)->unique(); 181 bool dstUnique = (*dst)->unique();
147 if (&src == *dst && dstUnique) { 182 if (!dstUnique) {
148 matrix.mapPoints((*dst)->fPoints, (*dst)->fPointCnt);
149 return;
150 } else if (!dstUnique) {
151 dst->reset(SkNEW(SkPathRef)); 183 dst->reset(SkNEW(SkPathRef));
184 (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt, src.fConicWeights.c ount());
185 memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * sizeof(uint8_t));
186 (*dst)->fConicWeights = src.fConicWeights;
152 } 187 }
153 (*dst)->resetToSize(src.fVerbCnt, src.fPointCnt, src.fConicWeights.count ()); 188
154 memcpy((*dst)->verbsMemWritable(), src.verbsMemBegin(), src.fVerbCnt * s izeof(uint8_t)); 189 // Need to check this here in case (&src == dst)
190 bool canXformBounds = !src.fBoundsIsDirty && matrix.rectStaysRect() && s rc.countPoints() > 1;
191
155 matrix.mapPoints((*dst)->fPoints, src.points(), src.fPointCnt); 192 matrix.mapPoints((*dst)->fPoints, src.points(), src.fPointCnt);
156 (*dst)->fConicWeights = src.fConicWeights; 193
194 /*
195 * Here we optimize the bounds computation, by noting if the bounds are
196 * already known, and if so, we just transform those as well and mark
197 * them as "known", rather than force the transformed path to have to
198 * recompute them.
199 *
200 * Special gotchas if the path is effectively empty (<= 1 point) or
201 * if it is non-finite. In those cases bounds need to stay empty,
202 * regardless of the matrix.
203 */
204 if (canXformBounds) {
205 (*dst)->fBoundsIsDirty = false;
206 if (src.fIsFinite) {
207 matrix.mapRect(&(*dst)->fBounds, src.fBounds);
208 if (!((*dst)->fIsFinite = (*dst)->fBounds.isFinite())) {
209 (*dst)->fBounds.setEmpty();
210 }
211 } else {
212 (*dst)->fIsFinite = false;
213 (*dst)->fBounds.setEmpty();
214 }
215 } else {
216 (*dst)->fBoundsIsDirty = true;
217 }
218
157 (*dst)->validate(); 219 (*dst)->validate();
158 } 220 }
159 221
160 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer) { 222 static SkPathRef* CreateFromBuffer(SkRBuffer* buffer
223 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO O
224 , bool newFormat, int32_t oldPacked
225 #endif
226 ) {
161 SkPathRef* ref = SkNEW(SkPathRef); 227 SkPathRef* ref = SkNEW(SkPathRef);
228 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO O
229 if (newFormat) {
230 #endif
231 int32_t packed = buffer->readU32();
232
233 ref->fIsFinite = (packed >> kIsFinite_SerializationShift) & 1;
234 #ifndef DELETE_THIS_CODE_WHEN_SKPS_ARE_REBUILT_AT_V14_AND_ALL_OTHER_INSTANCES_TO O
235 } else {
236 ref->fIsFinite = (oldPacked >> SkPath::kOldIsFinite_SerializationShi ft) & 1;
237 }
238 #endif
239
162 ref->fGenerationID = buffer->readU32(); 240 ref->fGenerationID = buffer->readU32();
163 int32_t verbCount = buffer->readS32(); 241 int32_t verbCount = buffer->readS32();
164 int32_t pointCount = buffer->readS32(); 242 int32_t pointCount = buffer->readS32();
165 int32_t conicCount = buffer->readS32(); 243 int32_t conicCount = buffer->readS32();
166 ref->resetToSize(verbCount, pointCount, conicCount); 244 ref->resetToSize(verbCount, pointCount, conicCount);
167 245
168 SkASSERT(verbCount == ref->countVerbs()); 246 SkASSERT(verbCount == ref->countVerbs());
169 SkASSERT(pointCount == ref->countPoints()); 247 SkASSERT(pointCount == ref->countPoints());
170 SkASSERT(conicCount == ref->fConicWeights.count()); 248 SkASSERT(conicCount == ref->fConicWeights.count());
171 buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t)); 249 buffer->read(ref->verbsMemWritable(), verbCount * sizeof(uint8_t));
172 buffer->read(ref->fPoints, pointCount * sizeof(SkPoint)); 250 buffer->read(ref->fPoints, pointCount * sizeof(SkPoint));
173 buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar)); 251 buffer->read(ref->fConicWeights.begin(), conicCount * sizeof(SkScalar));
252 buffer->read(&ref->fBounds, sizeof(SkRect));
253 ref->fBoundsIsDirty = false;
174 return ref; 254 return ref;
175 } 255 }
176 256
177 /** 257 /**
178 * Rollsback a path ref to zero verbs and points with the assumption that th e path ref will be 258 * Rollsback a path ref to zero verbs and points with the assumption that th e path ref will be
179 * repopulated with approximately the same number of verbs and points. A new path ref is created 259 * repopulated with approximately the same number of verbs and points. A new path ref is created
180 * only if necessary. 260 * only if necessary.
181 */ 261 */
182 static void Rewind(SkAutoTUnref<SkPathRef>* pathRef) { 262 static void Rewind(SkAutoTUnref<SkPathRef>* pathRef) {
183 if ((*pathRef)->unique()) { 263 if ((*pathRef)->unique()) {
184 (*pathRef)->validate(); 264 (*pathRef)->validate();
265 (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFini te
185 (*pathRef)->fVerbCnt = 0; 266 (*pathRef)->fVerbCnt = 0;
186 (*pathRef)->fPointCnt = 0; 267 (*pathRef)->fPointCnt = 0;
187 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); 268 (*pathRef)->fFreeSpace = (*pathRef)->currSize();
188 (*pathRef)->fGenerationID = 0; 269 (*pathRef)->fGenerationID = 0;
189 (*pathRef)->fConicWeights.rewind(); 270 (*pathRef)->fConicWeights.rewind();
190 (*pathRef)->validate(); 271 (*pathRef)->validate();
191 } else { 272 } else {
192 int oldVCnt = (*pathRef)->countVerbs(); 273 int oldVCnt = (*pathRef)->countVerbs();
193 int oldPCnt = (*pathRef)->countPoints(); 274 int oldPCnt = (*pathRef)->countPoints();
194 pathRef->reset(SkNEW(SkPathRef)); 275 pathRef->reset(SkNEW(SkPathRef));
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 return true; 368 return true;
288 } 369 }
289 370
290 /** 371 /**
291 * Writes the path points and verbs to a buffer. 372 * Writes the path points and verbs to a buffer.
292 */ 373 */
293 void writeToBuffer(SkWBuffer* buffer) { 374 void writeToBuffer(SkWBuffer* buffer) {
294 this->validate(); 375 this->validate();
295 SkDEBUGCODE(size_t beforePos = buffer->pos();) 376 SkDEBUGCODE(size_t beforePos = buffer->pos();)
296 377
378 // Call getBounds() to ensure (as a side-effect) that fBounds
379 // and fIsFinite are computed.
380 const SkRect& bounds = this->getBounds();
381
382 int32_t packed = ((fIsFinite & 1) << kIsFinite_SerializationShift);
383 buffer->write32(packed);
384
297 // TODO: write gen ID here. Problem: We don't know if we're cross proces s or not from 385 // TODO: write gen ID here. Problem: We don't know if we're cross proces s or not from
298 // SkWBuffer. Until this is fixed we write 0. 386 // SkWBuffer. Until this is fixed we write 0.
299 buffer->write32(0); 387 buffer->write32(0);
300 buffer->write32(fVerbCnt); 388 buffer->write32(fVerbCnt);
301 buffer->write32(fPointCnt); 389 buffer->write32(fPointCnt);
302 buffer->write32(fConicWeights.count()); 390 buffer->write32(fConicWeights.count());
303 buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t)); 391 buffer->write(verbsMemBegin(), fVerbCnt * sizeof(uint8_t));
304 buffer->write(fPoints, fPointCnt * sizeof(SkPoint)); 392 buffer->write(fPoints, fPointCnt * sizeof(SkPoint));
305 buffer->write(fConicWeights.begin(), fConicWeights.bytes()); 393 buffer->write(fConicWeights.begin(), fConicWeights.bytes());
394 buffer->write(&bounds, sizeof(bounds));
306 395
307 SkASSERT(buffer->pos() - beforePos == (size_t) this->writeSize()); 396 SkASSERT(buffer->pos() - beforePos == (size_t) this->writeSize());
308 } 397 }
309 398
310 /** 399 /**
311 * Gets the number of bytes that would be written in writeBuffer() 400 * Gets the number of bytes that would be written in writeBuffer()
312 */ 401 */
313 uint32_t writeSize() { 402 uint32_t writeSize() {
314 return 4 * sizeof(uint32_t) + 403 return 5 * sizeof(uint32_t) +
315 fVerbCnt * sizeof(uint8_t) + 404 fVerbCnt * sizeof(uint8_t) +
316 fPointCnt * sizeof(SkPoint) + 405 fPointCnt * sizeof(SkPoint) +
317 fConicWeights.bytes(); 406 fConicWeights.bytes() +
407 sizeof(SkRect);
318 } 408 }
319 409
320 private: 410 private:
411 enum SerializationOffsets {
412 kIsFinite_SerializationShift = 25, // requires 1 bit
413 };
414
321 SkPathRef() { 415 SkPathRef() {
416 fBoundsIsDirty = true; // this also invalidates fIsFinite
322 fPointCnt = 0; 417 fPointCnt = 0;
323 fVerbCnt = 0; 418 fVerbCnt = 0;
324 fVerbs = NULL; 419 fVerbs = NULL;
325 fPoints = NULL; 420 fPoints = NULL;
326 fFreeSpace = 0; 421 fFreeSpace = 0;
327 fGenerationID = kEmptyGenID; 422 fGenerationID = kEmptyGenID;
328 SkDEBUGCODE(fEditorsAttached = 0;) 423 SkDEBUGCODE(fEditorsAttached = 0;)
329 this->validate(); 424 this->validate();
330 } 425 }
331 426
332 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe servePoints) { 427 void copy(const SkPathRef& ref, int additionalReserveVerbs, int additionalRe servePoints) {
333 this->validate(); 428 this->validate();
334 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count() , 429 this->resetToSize(ref.fVerbCnt, ref.fPointCnt, ref.fConicWeights.count() ,
335 additionalReserveVerbs, additionalReservePoints); 430 additionalReserveVerbs, additionalReservePoints);
336 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * siz eof(uint8_t)); 431 memcpy(this->verbsMemWritable(), ref.verbsMemBegin(), ref.fVerbCnt * siz eof(uint8_t));
337 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint)); 432 memcpy(this->fPoints, ref.fPoints, ref.fPointCnt * sizeof(SkPoint));
338 fConicWeights = ref.fConicWeights; 433 fConicWeights = ref.fConicWeights;
339 // We could call genID() here to force a real ID (instead of 0). However , if we're making 434 // We could call genID() here to force a real ID (instead of 0). However , if we're making
340 // a copy then presumably we intend to make a modification immediately a fterwards. 435 // a copy then presumably we intend to make a modification immediately a fterwards.
341 fGenerationID = ref.fGenerationID; 436 fGenerationID = ref.fGenerationID;
437 fBoundsIsDirty = ref.fBoundsIsDirty;
438 if (!fBoundsIsDirty) {
439 fBounds = ref.fBounds;
440 fIsFinite = ref.fIsFinite;
441 }
342 this->validate(); 442 this->validate();
343 } 443 }
344 444
445 // Return true if the computed bounds are finite.
446 static bool ComputePtBounds(SkRect* bounds, const SkPathRef& ref) {
447 int count = ref.countPoints();
448 if (count <= 1) { // we ignore just 1 point (moveto)
449 bounds->setEmpty();
450 return count ? ref.points()->isFinite() : true;
451 } else {
452 return bounds->setBoundsCheck(ref.points(), count);
453 }
454 }
455
456 // called, if dirty, by getBounds()
457 void computeBounds() const {
458 SkDEBUGCODE(this->validate();)
459 SkASSERT(fBoundsIsDirty);
460
461 fIsFinite = ComputePtBounds(&fBounds, *this);
462 fBoundsIsDirty = false;
463 }
464
345 /** Makes additional room but does not change the counts or change the genID */ 465 /** Makes additional room but does not change the counts or change the genID */
346 void incReserve(int additionalVerbs, int additionalPoints) { 466 void incReserve(int additionalVerbs, int additionalPoints) {
347 this->validate(); 467 this->validate();
348 size_t space = additionalVerbs * sizeof(uint8_t) + additionalPoints * si zeof (SkPoint); 468 size_t space = additionalVerbs * sizeof(uint8_t) + additionalPoints * si zeof (SkPoint);
349 this->makeSpace(space); 469 this->makeSpace(space);
350 this->validate(); 470 this->validate();
351 } 471 }
352 472
353 /** Resets the path ref with verbCount verbs and pointCount points, all unit ialized. Also 473 /** Resets the path ref with verbCount verbs and pointCount points, all unin itialized. Also
354 * allocates space for reserveVerb additional verbs and reservePoints addit ional points.*/ 474 * allocates space for reserveVerb additional verbs and reservePoints addit ional points.*/
355 void resetToSize(int verbCount, int pointCount, int conicCount, 475 void resetToSize(int verbCount, int pointCount, int conicCount,
356 int reserveVerbs = 0, int reservePoints = 0) { 476 int reserveVerbs = 0, int reservePoints = 0) {
357 this->validate(); 477 this->validate();
478 fBoundsIsDirty = true; // this also invalidates fIsFinite
358 fGenerationID = 0; 479 fGenerationID = 0;
359 480
360 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo unt; 481 size_t newSize = sizeof(uint8_t) * verbCount + sizeof(SkPoint) * pointCo unt;
361 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r eservePoints; 482 size_t newReserve = sizeof(uint8_t) * reserveVerbs + sizeof(SkPoint) * r eservePoints;
362 size_t minSize = newSize + newReserve; 483 size_t minSize = newSize + newReserve;
363 484
364 ptrdiff_t sizeDelta = this->currSize() - minSize; 485 ptrdiff_t sizeDelta = this->currSize() - minSize;
365 486
366 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) { 487 if (sizeDelta < 0 || static_cast<size_t>(sizeDelta) >= 3 * minSize) {
367 sk_free(fPoints); 488 sk_free(fPoints);
(...skipping 19 matching lines...) Expand all
387 * Increases the verb count by newVerbs and the point count be newPoints. Ne w verbs and points 508 * Increases the verb count by newVerbs and the point count be newPoints. Ne w verbs and points
388 * are uninitialized. 509 * are uninitialized.
389 */ 510 */
390 void grow(int newVerbs, int newPoints) { 511 void grow(int newVerbs, int newPoints) {
391 this->validate(); 512 this->validate();
392 size_t space = newVerbs * sizeof(uint8_t) + newPoints * sizeof (SkPoint) ; 513 size_t space = newVerbs * sizeof(uint8_t) + newPoints * sizeof (SkPoint) ;
393 this->makeSpace(space); 514 this->makeSpace(space);
394 fVerbCnt += newVerbs; 515 fVerbCnt += newVerbs;
395 fPointCnt += newPoints; 516 fPointCnt += newPoints;
396 fFreeSpace -= space; 517 fFreeSpace -= space;
518 fBoundsIsDirty = true; // this also invalidates fIsFinite
397 this->validate(); 519 this->validate();
398 } 520 }
399 521
400 /** 522 /**
401 * Increases the verb count 1, records the new verb, and creates room for th e requisite number 523 * Increases the verb count 1, records the new verb, and creates room for th e requisite number
402 * of additional points. A pointer to the first point is returned. Any new p oints are 524 * of additional points. A pointer to the first point is returned. Any new p oints are
403 * uninitialized. 525 * uninitialized.
404 */ 526 */
405 SkPoint* growForVerb(SkPath::Verb verb) { 527 SkPoint* growForVerb(SkPath::Verb verb) {
406 this->validate(); 528 this->validate();
(...skipping 23 matching lines...) Expand all
430 SkDEBUGFAIL("default is not reached"); 552 SkDEBUGFAIL("default is not reached");
431 pCnt = 0; 553 pCnt = 0;
432 } 554 }
433 size_t space = sizeof(uint8_t) + pCnt * sizeof (SkPoint); 555 size_t space = sizeof(uint8_t) + pCnt * sizeof (SkPoint);
434 this->makeSpace(space); 556 this->makeSpace(space);
435 this->fVerbs[~fVerbCnt] = verb; 557 this->fVerbs[~fVerbCnt] = verb;
436 SkPoint* ret = fPoints + fPointCnt; 558 SkPoint* ret = fPoints + fPointCnt;
437 fVerbCnt += 1; 559 fVerbCnt += 1;
438 fPointCnt += pCnt; 560 fPointCnt += pCnt;
439 fFreeSpace -= space; 561 fFreeSpace -= space;
562 fBoundsIsDirty = true; // this also invalidates fIsFinite
440 this->validate(); 563 this->validate();
441 return ret; 564 return ret;
442 } 565 }
443 566
444 /** 567 /**
445 * Ensures that the free space available in the path ref is >= size. The ver b and point counts 568 * Ensures that the free space available in the path ref is >= size. The ver b and point counts
446 * are not changed. 569 * are not changed.
447 */ 570 */
448 void makeSpace(size_t size) { 571 void makeSpace(size_t size) {
449 this->validate(); 572 this->validate();
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 void validate() const { 640 void validate() const {
518 SkASSERT(static_cast<ptrdiff_t>(fFreeSpace) >= 0); 641 SkASSERT(static_cast<ptrdiff_t>(fFreeSpace) >= 0);
519 SkASSERT(reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t> (fPoints) >= 0); 642 SkASSERT(reinterpret_cast<intptr_t>(fVerbs) - reinterpret_cast<intptr_t> (fPoints) >= 0);
520 SkASSERT((NULL == fPoints) == (NULL == fVerbs)); 643 SkASSERT((NULL == fPoints) == (NULL == fVerbs));
521 SkASSERT(!(NULL == fPoints && 0 != fFreeSpace)); 644 SkASSERT(!(NULL == fPoints && 0 != fFreeSpace));
522 SkASSERT(!(NULL == fPoints && 0 != fFreeSpace)); 645 SkASSERT(!(NULL == fPoints && 0 != fFreeSpace));
523 SkASSERT(!(NULL == fPoints && fPointCnt)); 646 SkASSERT(!(NULL == fPoints && fPointCnt));
524 SkASSERT(!(NULL == fVerbs && fVerbCnt)); 647 SkASSERT(!(NULL == fVerbs && fVerbCnt));
525 SkASSERT(this->currSize() == 648 SkASSERT(this->currSize() ==
526 fFreeSpace + sizeof(SkPoint) * fPointCnt + sizeof(uint8_t) * fV erbCnt); 649 fFreeSpace + sizeof(SkPoint) * fPointCnt + sizeof(uint8_t) * fV erbCnt);
650
651 #ifdef SK_DEBUG
652 if (!fBoundsIsDirty && !fBounds.isEmpty()) {
653 bool isFinite = true;
654 for (int i = 0; i < fPointCnt; ++i) {
655 SkASSERT(fPoints[i].fX >= fBounds.fLeft && fPoints[i].fX <= fBou nds.fRight &&
656 fPoints[i].fY >= fBounds.fTop && fPoints[i].fY <= fBoun ds.fBottom);
657 if (!fPoints[i].isFinite()) {
658 isFinite = false;
659 }
660 }
661 SkASSERT(SkToBool(fIsFinite) == isFinite);
662 }
663 #endif
527 } 664 }
528 665
529 enum { 666 enum {
530 kMinSize = 256, 667 kMinSize = 256,
531 }; 668 };
532 669
670 mutable SkRect fBounds;
671 mutable uint8_t fBoundsIsDirty;
672 mutable SkBool8 fIsFinite; // only meaningful if bounds are valid
673
533 SkPoint* fPoints; // points to begining of the allocation 674 SkPoint* fPoints; // points to begining of the allocation
534 uint8_t* fVerbs; // points just past the end of the allocation (v erbs grow backwards) 675 uint8_t* fVerbs; // points just past the end of the allocation (v erbs grow backwards)
535 int fVerbCnt; 676 int fVerbCnt;
536 int fPointCnt; 677 int fPointCnt;
537 size_t fFreeSpace; // redundant but saves computation 678 size_t fFreeSpace; // redundant but saves computation
538 SkTDArray<SkScalar> fConicWeights; 679 SkTDArray<SkScalar> fConicWeights;
539 680
540 enum { 681 enum {
541 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer o verbs. 682 kEmptyGenID = 1, // GenID reserved for path ref with zero points and zer o verbs.
542 }; 683 };
543 mutable int32_t fGenerationID; 684 mutable int32_t fGenerationID;
544 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use at any time. 685 SkDEBUGCODE(int32_t fEditorsAttached;) // assert that only one editor in use at any time.
545 686
546 typedef SkRefCnt INHERITED; 687 typedef SkRefCnt INHERITED;
547 }; 688 };
548 689
549 SK_DEFINE_INST_COUNT(SkPathRef); 690 SK_DEFINE_INST_COUNT(SkPathRef);
550 691
551 #endif 692 #endif
OLDNEW
« include/core/SkPath.h ('K') | « src/core/SkPath.cpp ('k') | src/core/SkPicture.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698