OLD | NEW |
---|---|
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 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 "SkDashPathEffect.h" | 10 #include "SkDashPathEffect.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
27 } | 27 } |
28 } | 28 } |
29 // If we get here, phase "appears" to be larger than our length. This | 29 // If we get here, phase "appears" to be larger than our length. This |
30 // shouldn't happen with perfect precision, but we can accumulate errors | 30 // shouldn't happen with perfect precision, but we can accumulate errors |
31 // during the initial length computation (rounding can make our sum be too | 31 // during the initial length computation (rounding can make our sum be too |
32 // big or too small. In that event, we just have to eat the error here. | 32 // big or too small. In that event, we just have to eat the error here. |
33 *index = 0; | 33 *index = 0; |
34 return intervals[0]; | 34 return intervals[0]; |
35 } | 35 } |
36 | 36 |
37 SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, | 37 void SkDashPathEffect::setInternalMembers(SkScalar phase) { |
38 SkScalar phase) { | |
39 SkASSERT(intervals); | |
40 SkASSERT(count > 1 && SkAlign2(count) == count); | |
41 | |
42 fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count); | |
43 fCount = count; | |
44 | |
45 SkScalar len = 0; | 38 SkScalar len = 0; |
46 for (int i = 0; i < count; i++) { | 39 for (int i = 0; i < fCount; i++) { |
47 SkASSERT(intervals[i] >= 0); | 40 len += fIntervals[i]; |
48 fIntervals[i] = intervals[i]; | |
49 len += intervals[i]; | |
50 } | 41 } |
51 fIntervalLength = len; | 42 fIntervalLength = len; |
52 | 43 |
53 // watch out for values that might make us go out of bounds | 44 // watch out for values that might make us go out of bounds |
54 if ((len > 0) && SkScalarIsFinite(phase) && SkScalarIsFinite(len)) { | 45 if ((len > 0) && SkScalarIsFinite(phase) && SkScalarIsFinite(len)) { |
55 | 46 |
56 // Adjust phase to be between 0 and len, "flipping" phase if negative. | 47 // Adjust phase to be between 0 and len, "flipping" phase if negative. |
57 // e.g., if len is 100, then phase of -20 (or -120) is equivalent to 80 | 48 // e.g., if len is 100, then phase of -20 (or -120) is equivalent to 80 |
58 if (phase < 0) { | 49 if (phase < 0) { |
59 phase = -phase; | 50 phase = -phase; |
60 if (phase > len) { | 51 if (phase > len) { |
61 phase = SkScalarMod(phase, len); | 52 phase = SkScalarMod(phase, len); |
62 } | 53 } |
63 phase = len - phase; | 54 phase = len - phase; |
64 | 55 |
65 // Due to finite precision, it's possible that phase == len, | 56 // Due to finite precision, it's possible that phase == len, |
66 // even after the subtract (if len >>> phase), so fix that here. | 57 // even after the subtract (if len >>> phase), so fix that here. |
67 // This fixes http://crbug.com/124652 . | 58 // This fixes http://crbug.com/124652 . |
68 SkASSERT(phase <= len); | 59 SkASSERT(phase <= len); |
69 if (phase == len) { | 60 if (phase == len) { |
70 phase = 0; | 61 phase = 0; |
71 } | 62 } |
72 } else if (phase >= len) { | 63 } else if (phase >= len) { |
73 phase = SkScalarMod(phase, len); | 64 phase = SkScalarMod(phase, len); |
74 } | 65 } |
75 SkASSERT(phase >= 0 && phase < len); | 66 SkASSERT(phase >= 0 && phase < len); |
76 | 67 |
77 fInitialDashLength = FindFirstInterval(intervals, phase, | 68 fPhase = phase; |
78 &fInitialDashIndex, count); | 69 |
70 fInitialDashLength = FindFirstInterval(fIntervals, fPhase, | |
71 &fInitialDashIndex, fCount); | |
79 | 72 |
80 SkASSERT(fInitialDashLength >= 0); | 73 SkASSERT(fInitialDashLength >= 0); |
81 SkASSERT(fInitialDashIndex >= 0 && fInitialDashIndex < fCount); | 74 SkASSERT(fInitialDashIndex >= 0 && fInitialDashIndex < fCount); |
82 } else { | 75 } else { |
83 fInitialDashLength = -1; // signal bad dash intervals | 76 fInitialDashLength = -1; // signal bad dash intervals |
84 } | 77 } |
85 } | 78 } |
86 | 79 |
80 SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count, | |
81 SkScalar phase) { | |
82 SkASSERT(intervals); | |
83 SkASSERT(count > 1 && SkAlign2(count) == count); | |
84 | |
85 fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count); | |
86 fCount = count; | |
87 for (int i = 0; i < count; i++) { | |
88 SkASSERT(intervals[i] >= 0); | |
89 fIntervals[i] = intervals[i]; | |
90 } | |
91 | |
92 this->setInternalMembers(phase); | |
93 } | |
94 | |
87 SkDashPathEffect::~SkDashPathEffect() { | 95 SkDashPathEffect::~SkDashPathEffect() { |
88 sk_free(fIntervals); | 96 sk_free(fIntervals); |
89 } | 97 } |
90 | 98 |
91 static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) { | 99 static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) { |
92 SkScalar radius = SkScalarHalf(rec.getWidth()); | 100 SkScalar radius = SkScalarHalf(rec.getWidth()); |
93 if (0 == radius) { | 101 if (0 == radius) { |
94 radius = SK_Scalar1; // hairlines | 102 radius = SK_Scalar1; // hairlines |
95 } | 103 } |
96 if (SkPaint::kMiter_Join == rec.getJoin()) { | 104 if (SkPaint::kMiter_Join == rec.getJoin()) { |
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
503 results->fLast.addRect(x - halfWidth, y - halfHeight, | 511 results->fLast.addRect(x - halfWidth, y - halfHeight, |
504 x + halfWidth, y + halfHeight); | 512 x + halfWidth, y + halfHeight); |
505 } | 513 } |
506 | 514 |
507 SkASSERT(curPt == results->fNumPoints); | 515 SkASSERT(curPt == results->fNumPoints); |
508 } | 516 } |
509 | 517 |
510 return true; | 518 return true; |
511 } | 519 } |
512 | 520 |
521 SkPathEffect::DashType SkDashPathEffect::asADash(DashInfo* info) const { | |
522 if (info) { | |
523 if (info->fCount >= fCount) { | |
reed1
2014/04/22 14:15:02
nit:
if (info->fCount >= fCount && NULL != info->
| |
524 if (info->fIntervals) { | |
525 memcpy(info->fIntervals, fIntervals, fCount * sizeof(SkScalar)); | |
526 } | |
527 } | |
528 info->fCount = fCount; | |
529 info->fPhase = fPhase; | |
530 } | |
531 return kDash_DashType; | |
532 } | |
533 | |
513 SkFlattenable::Factory SkDashPathEffect::getFactory() const { | 534 SkFlattenable::Factory SkDashPathEffect::getFactory() const { |
514 return CreateProc; | 535 return CreateProc; |
515 } | 536 } |
516 | 537 |
517 void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const { | 538 void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const { |
518 this->INHERITED::flatten(buffer); | 539 this->INHERITED::flatten(buffer); |
519 buffer.writeInt(fInitialDashIndex); | 540 buffer.writeScalar(fPhase); |
520 buffer.writeScalar(fInitialDashLength); | |
521 buffer.writeScalar(fIntervalLength); | |
522 // Dummy write to stay compatible with old skps. Write will be removed in fo llow up patch. | |
523 buffer.writeBool(false); | |
524 buffer.writeScalarArray(fIntervals, fCount); | 541 buffer.writeScalarArray(fIntervals, fCount); |
525 } | 542 } |
526 | 543 |
527 SkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) { | 544 SkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) { |
528 return SkNEW_ARGS(SkDashPathEffect, (buffer)); | 545 return SkNEW_ARGS(SkDashPathEffect, (buffer)); |
529 } | 546 } |
530 | 547 |
531 SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { | 548 SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { |
532 fInitialDashIndex = buffer.readInt(); | 549 bool useOldPic = buffer.pictureVersion() < 25 && 0 != buffer.pictureVersion( ); |
533 fInitialDashLength = buffer.readScalar(); | 550 if (useOldPic) { |
534 fIntervalLength = buffer.readScalar(); | 551 fInitialDashIndex = buffer.readInt(); |
535 buffer.readBool(); // dummy read to stay compatible with old skps | 552 fInitialDashLength = buffer.readScalar(); |
553 fIntervalLength = buffer.readScalar(); | |
554 buffer.readBool(); // Dummy for old ScalarToFit field | |
555 } else { | |
556 fPhase = buffer.readScalar(); | |
557 } | |
536 | 558 |
537 fCount = buffer.getArrayCount(); | 559 fCount = buffer.getArrayCount(); |
538 size_t allocSize = sizeof(SkScalar) * fCount; | 560 size_t allocSize = sizeof(SkScalar) * fCount; |
539 if (buffer.validateAvailable(allocSize)) { | 561 if (buffer.validateAvailable(allocSize)) { |
540 fIntervals = (SkScalar*)sk_malloc_throw(allocSize); | 562 fIntervals = (SkScalar*)sk_malloc_throw(allocSize); |
541 buffer.readScalarArray(fIntervals, fCount); | 563 buffer.readScalarArray(fIntervals, fCount); |
542 } else { | 564 } else { |
543 fIntervals = NULL; | 565 fIntervals = NULL; |
544 } | 566 } |
567 | |
568 if (useOldPic) { | |
569 fPhase = 0.0; | |
reed1
2014/04/22 14:15:02
may get a double-warning: Try just fPhase = 0;
| |
570 for (int i = 0; i < fInitialDashIndex; ++i) { | |
571 fPhase += fIntervals[i]; | |
572 } | |
573 fPhase += fInitialDashLength; | |
574 } else { | |
575 this->setInternalMembers(fPhase); | |
576 } | |
545 } | 577 } |
OLD | NEW |