Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Side by Side Diff: src/effects/SkDashPathEffect.cpp

Issue 212103010: Add asADash entry point into SkPathEffect to allow extracting Dash info from PathEffects (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Constructor Fix Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/core/SkPathEffect.cpp ('k') | tests/AsADashTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « src/core/SkPathEffect.cpp ('k') | tests/AsADashTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698