| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkBuffer.h" | 8 #include "SkBuffer.h" |
| 9 #include "SkOnce.h" | 9 #include "SkOnce.h" |
| 10 #include "SkPath.h" | 10 #include "SkPath.h" |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 | 147 |
| 148 // resetToSize clears fSegmentMask and fIsOval | 148 // resetToSize clears fSegmentMask and fIsOval |
| 149 ref->fSegmentMask = segmentMask; | 149 ref->fSegmentMask = segmentMask; |
| 150 ref->fIsOval = isOval; | 150 ref->fIsOval = isOval; |
| 151 return ref; | 151 return ref; |
| 152 } | 152 } |
| 153 | 153 |
| 154 void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) { | 154 void SkPathRef::Rewind(SkAutoTUnref<SkPathRef>* pathRef) { |
| 155 if ((*pathRef)->unique()) { | 155 if ((*pathRef)->unique()) { |
| 156 SkDEBUGCODE((*pathRef)->validate();) | 156 SkDEBUGCODE((*pathRef)->validate();) |
| 157 (*pathRef)->fLastMoveToIndex = kINITIAL_LASTMOVETOINDEX_VALUE; |
| 157 (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFinite | 158 (*pathRef)->fBoundsIsDirty = true; // this also invalidates fIsFinite |
| 158 (*pathRef)->fVerbCnt = 0; | 159 (*pathRef)->fVerbCnt = 0; |
| 159 (*pathRef)->fPointCnt = 0; | 160 (*pathRef)->fPointCnt = 0; |
| 160 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); | 161 (*pathRef)->fFreeSpace = (*pathRef)->currSize(); |
| 161 (*pathRef)->fGenerationID = 0; | 162 (*pathRef)->fGenerationID = 0; |
| 162 (*pathRef)->fConicWeights.rewind(); | 163 (*pathRef)->fConicWeights.rewind(); |
| 163 (*pathRef)->fSegmentMask = 0; | 164 (*pathRef)->fSegmentMask = 0; |
| 164 (*pathRef)->fIsOval = false; | 165 (*pathRef)->fIsOval = false; |
| 165 SkDEBUGCODE((*pathRef)->validate();) | 166 SkDEBUGCODE((*pathRef)->validate();) |
| 166 } else { | 167 } else { |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 269 fBoundsIsDirty = ref.fBoundsIsDirty; | 270 fBoundsIsDirty = ref.fBoundsIsDirty; |
| 270 if (!fBoundsIsDirty) { | 271 if (!fBoundsIsDirty) { |
| 271 fBounds = ref.fBounds; | 272 fBounds = ref.fBounds; |
| 272 fIsFinite = ref.fIsFinite; | 273 fIsFinite = ref.fIsFinite; |
| 273 } | 274 } |
| 274 fSegmentMask = ref.fSegmentMask; | 275 fSegmentMask = ref.fSegmentMask; |
| 275 fIsOval = ref.fIsOval; | 276 fIsOval = ref.fIsOval; |
| 276 SkDEBUGCODE(this->validate();) | 277 SkDEBUGCODE(this->validate();) |
| 277 } | 278 } |
| 278 | 279 |
| 280 void SkPathRef::injectMoveToIfNeeded() { |
| 281 if (fLastMoveToIndex < 0) { |
| 282 SkScalar x, y; |
| 283 if (this->countVerbs() == 0) { |
| 284 x = y = 0; |
| 285 } else { |
| 286 const SkPoint& pt = this->atPoint(~fLastMoveToIndex); |
| 287 x = pt.fX; |
| 288 y = pt.fY; |
| 289 } |
| 290 this->growForVerb(SkPath::kMove_Verb, 0)->set(x, y); |
| 291 } |
| 292 } |
| 293 |
| 279 SkPoint* SkPathRef::growForRepeatedVerb(int /*SkPath::Verb*/ verb, | 294 SkPoint* SkPathRef::growForRepeatedVerb(int /*SkPath::Verb*/ verb, |
| 280 int numVbs, | 295 int numVbs, |
| 281 SkScalar** weights) { | 296 SkScalar** weights) { |
| 282 // This value is just made-up for now. When count is 4, calling memset was m
uch | 297 // This value is just made-up for now. When count is 4, calling memset was m
uch |
| 283 // slower than just writing the loop. This seems odd, and hopefully in the | 298 // slower than just writing the loop. This seems odd, and hopefully in the |
| 284 // future this will appear to have been a fluke... | 299 // future this will appear to have been a fluke... |
| 285 static const unsigned int kMIN_COUNT_FOR_MEMSET_TO_BE_FAST = 16; | 300 static const unsigned int kMIN_COUNT_FOR_MEMSET_TO_BE_FAST = 16; |
| 286 | 301 |
| 302 if (numVbs <= 0) { |
| 303 return NULL; |
| 304 } |
| 305 |
| 287 SkDEBUGCODE(this->validate();) | 306 SkDEBUGCODE(this->validate();) |
| 288 int pCnt; | 307 int pCnt; |
| 289 bool dirtyAfterEdit = true; | 308 bool dirtyAfterEdit = true; |
| 290 switch (verb) { | 309 switch (verb) { |
| 291 case SkPath::kMove_Verb: | 310 case SkPath::kMove_Verb: |
| 311 fLastMoveToIndex = fPointCnt + numVbs - 1; |
| 292 pCnt = numVbs; | 312 pCnt = numVbs; |
| 293 dirtyAfterEdit = false; | 313 dirtyAfterEdit = false; |
| 294 break; | 314 break; |
| 295 case SkPath::kLine_Verb: | 315 case SkPath::kLine_Verb: |
| 296 fSegmentMask |= SkPath::kLine_SegmentMask; | 316 fSegmentMask |= SkPath::kLine_SegmentMask; |
| 297 pCnt = numVbs; | 317 pCnt = numVbs; |
| 298 break; | 318 break; |
| 299 case SkPath::kQuad_Verb: | 319 case SkPath::kQuad_Verb: |
| 300 fSegmentMask |= SkPath::kQuad_SegmentMask; | 320 fSegmentMask |= SkPath::kQuad_SegmentMask; |
| 301 pCnt = 2 * numVbs; | 321 pCnt = 2 * numVbs; |
| 302 break; | 322 break; |
| 303 case SkPath::kConic_Verb: | 323 case SkPath::kConic_Verb: |
| 304 fSegmentMask |= SkPath::kConic_SegmentMask; | 324 fSegmentMask |= SkPath::kConic_SegmentMask; |
| 305 pCnt = 2 * numVbs; | 325 pCnt = 2 * numVbs; |
| 306 break; | 326 break; |
| 307 case SkPath::kCubic_Verb: | 327 case SkPath::kCubic_Verb: |
| 308 fSegmentMask |= SkPath::kCubic_SegmentMask; | 328 fSegmentMask |= SkPath::kCubic_SegmentMask; |
| 309 pCnt = 3 * numVbs; | 329 pCnt = 3 * numVbs; |
| 310 break; | 330 break; |
| 311 case SkPath::kClose_Verb: | 331 case SkPath::kClose_Verb: |
| 312 SkDEBUGFAIL("growForRepeatedVerb called for kClose_Verb"); | 332 SkDEBUGFAIL("growForRepeatedVerb called for kClose_Verb"); |
| 333 // signal that we need a moveTo to follow us (unless we're done) |
| 334 fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToInde
x) - 1); |
| 313 pCnt = 0; | 335 pCnt = 0; |
| 314 dirtyAfterEdit = false; | 336 dirtyAfterEdit = false; |
| 315 break; | 337 break; |
| 316 case SkPath::kDone_Verb: | 338 case SkPath::kDone_Verb: |
| 317 SkDEBUGFAIL("growForRepeatedVerb called for kDone"); | 339 SkDEBUGFAIL("growForRepeatedVerb called for kDone"); |
| 318 // fall through | 340 // fall through |
| 319 default: | 341 default: |
| 320 SkDEBUGFAIL("default should not be reached"); | 342 SkDEBUGFAIL("default should not be reached"); |
| 321 pCnt = 0; | 343 pCnt = 0; |
| 322 dirtyAfterEdit = false; | 344 dirtyAfterEdit = false; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 SkDEBUGCODE(this->validate();) | 376 SkDEBUGCODE(this->validate();) |
| 355 return ret; | 377 return ret; |
| 356 } | 378 } |
| 357 | 379 |
| 358 SkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb, SkScalar weight) { | 380 SkPoint* SkPathRef::growForVerb(int /* SkPath::Verb*/ verb, SkScalar weight) { |
| 359 SkDEBUGCODE(this->validate();) | 381 SkDEBUGCODE(this->validate();) |
| 360 int pCnt; | 382 int pCnt; |
| 361 bool dirtyAfterEdit = true; | 383 bool dirtyAfterEdit = true; |
| 362 switch (verb) { | 384 switch (verb) { |
| 363 case SkPath::kMove_Verb: | 385 case SkPath::kMove_Verb: |
| 386 // remember our index |
| 387 fLastMoveToIndex = fPointCnt; |
| 364 pCnt = 1; | 388 pCnt = 1; |
| 365 dirtyAfterEdit = false; | 389 dirtyAfterEdit = false; |
| 366 break; | 390 break; |
| 367 case SkPath::kLine_Verb: | 391 case SkPath::kLine_Verb: |
| 368 fSegmentMask |= SkPath::kLine_SegmentMask; | 392 fSegmentMask |= SkPath::kLine_SegmentMask; |
| 369 pCnt = 1; | 393 pCnt = 1; |
| 370 break; | 394 break; |
| 371 case SkPath::kQuad_Verb: | 395 case SkPath::kQuad_Verb: |
| 372 fSegmentMask |= SkPath::kQuad_SegmentMask; | 396 fSegmentMask |= SkPath::kQuad_SegmentMask; |
| 373 pCnt = 2; | 397 pCnt = 2; |
| 374 break; | 398 break; |
| 375 case SkPath::kConic_Verb: | 399 case SkPath::kConic_Verb: |
| 376 fSegmentMask |= SkPath::kConic_SegmentMask; | 400 fSegmentMask |= SkPath::kConic_SegmentMask; |
| 377 pCnt = 2; | 401 pCnt = 2; |
| 378 break; | 402 break; |
| 379 case SkPath::kCubic_Verb: | 403 case SkPath::kCubic_Verb: |
| 380 fSegmentMask |= SkPath::kCubic_SegmentMask; | 404 fSegmentMask |= SkPath::kCubic_SegmentMask; |
| 381 pCnt = 3; | 405 pCnt = 3; |
| 382 break; | 406 break; |
| 383 case SkPath::kClose_Verb: | 407 case SkPath::kClose_Verb: |
| 408 // signal that we need a moveTo to follow us (unless we're done) |
| 409 fLastMoveToIndex ^= ~fLastMoveToIndex >> (8 * sizeof(fLastMoveToInde
x) - 1); |
| 384 pCnt = 0; | 410 pCnt = 0; |
| 385 dirtyAfterEdit = false; | 411 dirtyAfterEdit = false; |
| 386 break; | 412 break; |
| 387 case SkPath::kDone_Verb: | 413 case SkPath::kDone_Verb: |
| 388 SkDEBUGFAIL("growForVerb called for kDone"); | 414 SkDEBUGFAIL("growForVerb called for kDone"); |
| 389 // fall through | 415 // fall through |
| 390 default: | 416 default: |
| 391 SkDEBUGFAIL("default is not reached"); | 417 SkDEBUGFAIL("default is not reached"); |
| 392 dirtyAfterEdit = false; | 418 dirtyAfterEdit = false; |
| 393 pCnt = 0; | 419 pCnt = 0; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 fPoints[i].fY - fBounds.fBottom < SK_ScalarNearlyZero)); | 479 fPoints[i].fY - fBounds.fBottom < SK_ScalarNearlyZero)); |
| 454 if (!fPoints[i].isFinite()) { | 480 if (!fPoints[i].isFinite()) { |
| 455 isFinite = false; | 481 isFinite = false; |
| 456 } | 482 } |
| 457 } | 483 } |
| 458 SkASSERT(SkToBool(fIsFinite) == isFinite); | 484 SkASSERT(SkToBool(fIsFinite) == isFinite); |
| 459 } | 485 } |
| 460 | 486 |
| 461 #ifdef SK_DEBUG_PATH | 487 #ifdef SK_DEBUG_PATH |
| 462 uint32_t mask = 0; | 488 uint32_t mask = 0; |
| 489 int lastMoveToIndex = kINITIAL_LASTMOVETOINDEX_VALUE; |
| 490 int pointCnt = 0; |
| 463 for (int i = 0; i < fVerbCnt; ++i) { | 491 for (int i = 0; i < fVerbCnt; ++i) { |
| 464 switch (fVerbs[~i]) { | 492 switch (fVerbs[~i]) { |
| 465 case SkPath::kMove_Verb: | 493 case SkPath::kMove_Verb: |
| 494 lastMoveToIndex = pointCnt; |
| 495 ++pointCnt; |
| 466 break; | 496 break; |
| 467 case SkPath::kLine_Verb: | 497 case SkPath::kLine_Verb: |
| 468 mask |= SkPath::kLine_SegmentMask; | 498 mask |= SkPath::kLine_SegmentMask; |
| 499 ++pointCnt; |
| 469 break; | 500 break; |
| 470 case SkPath::kQuad_Verb: | 501 case SkPath::kQuad_Verb: |
| 471 mask |= SkPath::kQuad_SegmentMask; | 502 mask |= SkPath::kQuad_SegmentMask; |
| 503 pointCnt += 2; |
| 472 break; | 504 break; |
| 473 case SkPath::kConic_Verb: | 505 case SkPath::kConic_Verb: |
| 474 mask |= SkPath::kConic_SegmentMask; | 506 mask |= SkPath::kConic_SegmentMask; |
| 507 pointCnt += 2; |
| 475 break; | 508 break; |
| 476 case SkPath::kCubic_Verb: | 509 case SkPath::kCubic_Verb: |
| 477 mask |= SkPath::kCubic_SegmentMask; | 510 mask |= SkPath::kCubic_SegmentMask; |
| 511 pointCnt += 3; |
| 478 break; | 512 break; |
| 479 case SkPath::kClose_Verb: | 513 case SkPath::kClose_Verb: |
| 514 if (lastMoveToIndex >= 0) { |
| 515 lastMoveToIndex = ~lastMoveToIndex; |
| 516 } |
| 480 break; | 517 break; |
| 481 case SkPath::kDone_Verb: | 518 case SkPath::kDone_Verb: |
| 482 SkDEBUGFAIL("Done verb shouldn't be recorded."); | 519 SkDEBUGFAIL("Done verb shouldn't be recorded."); |
| 483 break; | 520 break; |
| 484 default: | 521 default: |
| 485 SkDEBUGFAIL("Unknown Verb"); | 522 SkDEBUGFAIL("Unknown Verb"); |
| 486 break; | 523 break; |
| 487 } | 524 } |
| 488 } | 525 } |
| 489 SkASSERT(mask == fSegmentMask); | 526 SkASSERT(mask == fSegmentMask); |
| 527 SkASSERT(lastMoveToIndex == fLastMoveToIndex); |
| 528 SkASSERT(pointCnt == fPointCnt); |
| 490 #endif // SK_DEBUG_PATH | 529 #endif // SK_DEBUG_PATH |
| 491 } | 530 } |
| 492 #endif | 531 #endif |
| OLD | NEW |