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