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 |