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

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: Flatten Updates 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
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, bool scaleToFit)
39 : fScaleToFit(scaleToFit) {
40 SkASSERT(intervals);
41 SkASSERT(count > 1 && SkAlign2(count) == count);
42
43 fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count);
44 fCount = count;
45
46 SkScalar len = 0; 38 SkScalar len = 0;
47 for (int i = 0; i < count; i++) { 39 for (int i = 0; i < fCount; i++) {
48 SkASSERT(intervals[i] >= 0); 40 len += fIntervals[i];
49 fIntervals[i] = intervals[i];
50 len += intervals[i];
51 } 41 }
52 fIntervalLength = len; 42 fIntervalLength = len;
53 43
54 // 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
55 if ((len > 0) && SkScalarIsFinite(phase) && SkScalarIsFinite(len)) { 45 if ((len > 0) && SkScalarIsFinite(phase) && SkScalarIsFinite(len)) {
56 46
57 // 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.
58 // 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
59 if (phase < 0) { 49 if (phase < 0) {
60 phase = -phase; 50 phase = -phase;
61 if (phase > len) { 51 if (phase > len) {
62 phase = SkScalarMod(phase, len); 52 phase = SkScalarMod(phase, len);
63 } 53 }
64 phase = len - phase; 54 phase = len - phase;
65 55
66 // Due to finite precision, it's possible that phase == len, 56 // Due to finite precision, it's possible that phase == len,
67 // even after the subtract (if len >>> phase), so fix that here. 57 // even after the subtract (if len >>> phase), so fix that here.
68 // This fixes http://crbug.com/124652 . 58 // This fixes http://crbug.com/124652 .
69 SkASSERT(phase <= len); 59 SkASSERT(phase <= len);
70 if (phase == len) { 60 if (phase == len) {
71 phase = 0; 61 phase = 0;
72 } 62 }
73 } else if (phase >= len) { 63 } else if (phase >= len) {
74 phase = SkScalarMod(phase, len); 64 phase = SkScalarMod(phase, len);
75 } 65 }
76 SkASSERT(phase >= 0 && phase < len); 66 SkASSERT(phase >= 0 && phase < len);
77 67
78 fInitialDashLength = FindFirstInterval(intervals, phase, 68 fPhase = phase;
79 &fInitialDashIndex, count); 69
70 fInitialDashLength = FindFirstInterval(fIntervals, fPhase,
71 &fInitialDashIndex, fCount);
80 72
81 SkASSERT(fInitialDashLength >= 0); 73 SkASSERT(fInitialDashLength >= 0);
82 SkASSERT(fInitialDashIndex >= 0 && fInitialDashIndex < fCount); 74 SkASSERT(fInitialDashIndex >= 0 && fInitialDashIndex < fCount);
83 } else { 75 } else {
84 fInitialDashLength = -1; // signal bad dash intervals 76 fInitialDashLength = -1; // signal bad dash intervals
85 } 77 }
86 } 78 }
87 79
80 SkDashPathEffect::SkDashPathEffect(const SkScalar intervals[], int count,
81 SkScalar phase, bool scaleToFit)
82 : fScaleToFit(scaleToFit) {
83 SkASSERT(intervals);
84 SkASSERT(count > 1 && SkAlign2(count) == count);
85
86 fIntervals = (SkScalar*)sk_malloc_throw(sizeof(SkScalar) * count);
87 fCount = count;
88 for (int i = 0; i < count; i++) {
89 SkASSERT(intervals[i] >= 0);
90 fIntervals[i] = intervals[i];
91 }
92
93 this->setInternalMembers(phase);
94 }
95
88 SkDashPathEffect::~SkDashPathEffect() { 96 SkDashPathEffect::~SkDashPathEffect() {
89 sk_free(fIntervals); 97 sk_free(fIntervals);
90 } 98 }
91 99
92 static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) { 100 static void outset_for_stroke(SkRect* rect, const SkStrokeRec& rec) {
93 SkScalar radius = SkScalarHalf(rec.getWidth()); 101 SkScalar radius = SkScalarHalf(rec.getWidth());
94 if (0 == radius) { 102 if (0 == radius) {
95 radius = SK_Scalar1; // hairlines 103 radius = SK_Scalar1; // hairlines
96 } 104 }
97 if (SkPaint::kMiter_Join == rec.getJoin()) { 105 if (SkPaint::kMiter_Join == rec.getJoin()) {
(...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 results->fLast.addRect(x - halfWidth, y - halfHeight, 530 results->fLast.addRect(x - halfWidth, y - halfHeight,
523 x + halfWidth, y + halfHeight); 531 x + halfWidth, y + halfHeight);
524 } 532 }
525 533
526 SkASSERT(curPt == results->fNumPoints); 534 SkASSERT(curPt == results->fNumPoints);
527 } 535 }
528 536
529 return true; 537 return true;
530 } 538 }
531 539
540 SkPathEffect::DashType SkDashPathEffect::asADash(DashInfo* info) const {
541 if (info) {
542 if (info->fCount >= fCount) {
543 if (info->fIntervals) {
544 memcpy(info->fIntervals, fIntervals, fCount * sizeof(SkScalar));
545 }
546 }
547 info->fCount = fCount;
548 info->fPhase = fPhase;
549 info->fScaleToFit = fScaleToFit;
550 }
551 return kDash_DashType;
552 }
553
554 #define NEW_FLATTEN_VERSION 123
555
532 SkFlattenable::Factory SkDashPathEffect::getFactory() const { 556 SkFlattenable::Factory SkDashPathEffect::getFactory() const {
533 return CreateProc; 557 return CreateProc;
534 } 558 }
535 559
536 void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const { 560 void SkDashPathEffect::flatten(SkWriteBuffer& buffer) const {
537 this->INHERITED::flatten(buffer); 561 this->INHERITED::flatten(buffer);
538 buffer.writeInt(fInitialDashIndex); 562 if (buffer.pictureVersion() < NEW_FLATTEN_VERSION) {
bsalomon 2014/03/28 14:57:22 Do we need this? Will we ever write an old picture
539 buffer.writeScalar(fInitialDashLength); 563 buffer.writeInt(fInitialDashIndex);
540 buffer.writeScalar(fIntervalLength); 564 buffer.writeScalar(fInitialDashLength);
565 buffer.writeScalar(fIntervalLength);
566 } else {
567 buffer.writeScalar(fPhase);
568 }
541 buffer.writeBool(fScaleToFit); 569 buffer.writeBool(fScaleToFit);
542 buffer.writeScalarArray(fIntervals, fCount); 570 buffer.writeScalarArray(fIntervals, fCount);
543 } 571 }
544 572
545 SkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) { 573 SkFlattenable* SkDashPathEffect::CreateProc(SkReadBuffer& buffer) {
546 return SkNEW_ARGS(SkDashPathEffect, (buffer)); 574 return SkNEW_ARGS(SkDashPathEffect, (buffer));
547 } 575 }
548 576
549 SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { 577 SkDashPathEffect::SkDashPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
550 fInitialDashIndex = buffer.readInt(); 578 if (buffer.pictureVersion() < NEW_FLATTEN_VERSION) {
551 fInitialDashLength = buffer.readScalar(); 579 fInitialDashIndex = buffer.readInt();
552 fIntervalLength = buffer.readScalar(); 580 fInitialDashLength = buffer.readScalar();
581 fIntervalLength = buffer.readScalar();
582 } else {
583 fPhase = buffer.readScalar();
584 }
585
553 fScaleToFit = buffer.readBool(); 586 fScaleToFit = buffer.readBool();
554 587
555 fCount = buffer.getArrayCount(); 588 fCount = buffer.getArrayCount();
556 size_t allocSize = sizeof(SkScalar) * fCount; 589 size_t allocSize = sizeof(SkScalar) * fCount;
557 if (buffer.validateAvailable(allocSize)) { 590 if (buffer.validateAvailable(allocSize)) {
558 fIntervals = (SkScalar*)sk_malloc_throw(allocSize); 591 fIntervals = (SkScalar*)sk_malloc_throw(allocSize);
559 buffer.readScalarArray(fIntervals, fCount); 592 buffer.readScalarArray(fIntervals, fCount);
560 } else { 593 } else {
561 fIntervals = NULL; 594 fIntervals = NULL;
562 } 595 }
596
597 if (buffer.pictureVersion() < NEW_FLATTEN_VERSION) {
598 fPhase = 0.0;
599 for (int i = 0; i < fInitialDashIndex; ++i) {
600 fPhase += fIntervals[i];
601 }
602 fPhase += fInitialDashLength;
603 } else {
604 this->setInternalMembers(fPhase);
605 }
563 } 606 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698