OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2008 The Android Open Source Project | 3 * Copyright 2008 The Android Open Source Project |
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 | 9 |
10 #include "SkPathMeasure.h" | 10 #include "SkPathMeasure.h" |
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 if (fPath == NULL) { | 435 if (fPath == NULL) { |
436 return 0; | 436 return 0; |
437 } | 437 } |
438 if (fLength < 0) { | 438 if (fLength < 0) { |
439 this->buildSegments(); | 439 this->buildSegments(); |
440 } | 440 } |
441 SkASSERT(fLength >= 0); | 441 SkASSERT(fLength >= 0); |
442 return fLength; | 442 return fLength; |
443 } | 443 } |
444 | 444 |
| 445 template <typename T, typename K> |
| 446 int SkTKSearch(const T base[], int count, const K& key) { |
| 447 SkASSERT(count >= 0); |
| 448 if (count <= 0) { |
| 449 return ~0; |
| 450 } |
| 451 |
| 452 SkASSERT(base != NULL); // base may be NULL if count is zero |
| 453 |
| 454 int lo = 0; |
| 455 int hi = count - 1; |
| 456 |
| 457 while (lo < hi) { |
| 458 int mid = (hi + lo) >> 1; |
| 459 if (base[mid].fDistance < key) { |
| 460 lo = mid + 1; |
| 461 } else { |
| 462 hi = mid; |
| 463 } |
| 464 } |
| 465 |
| 466 if (base[hi].fDistance < key) { |
| 467 hi += 1; |
| 468 hi = ~hi; |
| 469 } else if (key < base[hi].fDistance) { |
| 470 hi = ~hi; |
| 471 } |
| 472 return hi; |
| 473 } |
| 474 |
445 const SkPathMeasure::Segment* SkPathMeasure::distanceToSegment( | 475 const SkPathMeasure::Segment* SkPathMeasure::distanceToSegment( |
446 SkScalar distance, SkScalar* t) { | 476 SkScalar distance, SkScalar* t) { |
447 SkDEBUGCODE(SkScalar length = ) this->getLength(); | 477 SkDEBUGCODE(SkScalar length = ) this->getLength(); |
448 SkASSERT(distance >= 0 && distance <= length); | 478 SkASSERT(distance >= 0 && distance <= length); |
449 | 479 |
450 const Segment* seg = fSegments.begin(); | 480 const Segment* seg = fSegments.begin(); |
451 int count = fSegments.count(); | 481 int count = fSegments.count(); |
452 | 482 |
453 int index = SkTSearch<SkScalar>(&seg->fDistance, count, distance, sizeof(Seg
ment)); | 483 int index = SkTKSearch<Segment, SkScalar>(seg, count, distance); |
454 // don't care if we hit an exact match or not, so we xor index if it is nega
tive | 484 // don't care if we hit an exact match or not, so we xor index if it is nega
tive |
455 index ^= (index >> 31); | 485 index ^= (index >> 31); |
456 seg = &seg[index]; | 486 seg = &seg[index]; |
457 | 487 |
458 // now interpolate t-values with the prev segment (if possible) | 488 // now interpolate t-values with the prev segment (if possible) |
459 SkScalar startT = 0, startD = 0; | 489 SkScalar startT = 0, startD = 0; |
460 // check if the prev segment is legal, and references the same set of points | 490 // check if the prev segment is legal, and references the same set of points |
461 if (index > 0) { | 491 if (index > 0) { |
462 startD = seg[-1].fDistance; | 492 startD = seg[-1].fDistance; |
463 if (seg[-1].fPtIndex == seg->fPtIndex) { | 493 if (seg[-1].fPtIndex == seg->fPtIndex) { |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 | 621 |
592 for (int i = 0; i < fSegments.count(); i++) { | 622 for (int i = 0; i < fSegments.count(); i++) { |
593 const Segment* seg = &fSegments[i]; | 623 const Segment* seg = &fSegments[i]; |
594 SkDebugf("pathmeas: seg[%d] distance=%g, point=%d, t=%g, type=%d\n", | 624 SkDebugf("pathmeas: seg[%d] distance=%g, point=%d, t=%g, type=%d\n", |
595 i, seg->fDistance, seg->fPtIndex, seg->getScalarT(), | 625 i, seg->fDistance, seg->fPtIndex, seg->getScalarT(), |
596 seg->fType); | 626 seg->fType); |
597 } | 627 } |
598 } | 628 } |
599 | 629 |
600 #endif | 630 #endif |
OLD | NEW |