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

Side by Side Diff: src/effects/gradients/SkGradientShader.cpp

Issue 15733007: use Descriptor struct to encapsulate all the common paramaeters between our various gradient types.… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
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 "SkGradientShaderPriv.h" 8 #include "SkGradientShaderPriv.h"
9 #include "SkLinearGradient.h" 9 #include "SkLinearGradient.h"
10 #include "SkRadialGradient.h" 10 #include "SkRadialGradient.h"
11 #include "SkTwoPointRadialGradient.h" 11 #include "SkTwoPointRadialGradient.h"
12 #include "SkTwoPointConicalGradient.h" 12 #include "SkTwoPointConicalGradient.h"
13 #include "SkSweepGradient.h" 13 #include "SkSweepGradient.h"
14 14
15 SkGradientShaderBase::SkGradientShaderBase(const SkColor colors[], const SkScala r pos[], 15 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) {
16 int colorCount, SkShader::TileMode mode, SkUnitMapper* mapper) { 16 SkASSERT(desc.fCount > 1);
17 SkASSERT(colorCount > 1);
18 17
19 fCacheAlpha = 256; // init to a value that paint.getAlpha() can't return 18 fCacheAlpha = 256; // init to a value that paint.getAlpha() can't return
20 19
21 fMapper = mapper; 20 fMapper = desc.fMapper;
22 SkSafeRef(mapper); 21 SkSafeRef(fMapper);
23 22
24 SkASSERT((unsigned)mode < SkShader::kTileModeCount); 23 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount);
25 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs)); 24 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs));
26 fTileMode = mode; 25 fTileMode = desc.fTileMode;
27 fTileProc = gTileProcs[mode]; 26 fTileProc = gTileProcs[desc.fTileMode];
28 27
29 fCache16 = fCache16Storage = NULL; 28 fCache16 = fCache16Storage = NULL;
30 fCache32 = NULL; 29 fCache32 = NULL;
31 fCache32PixelRef = NULL; 30 fCache32PixelRef = NULL;
32 31
33 /* Note: we let the caller skip the first and/or last position. 32 /* Note: we let the caller skip the first and/or last position.
34 i.e. pos[0] = 0.3, pos[1] = 0.7 33 i.e. pos[0] = 0.3, pos[1] = 0.7
35 In these cases, we insert dummy entries to ensure that the final data 34 In these cases, we insert dummy entries to ensure that the final data
36 will be bracketed by [0, 1]. 35 will be bracketed by [0, 1].
37 i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1 36 i.e. our_pos[0] = 0, our_pos[1] = 0.3, our_pos[2] = 0.7, our_pos[3] = 1
38 37
39 Thus colorCount (the caller's value, and fColorCount (our value) may 38 Thus colorCount (the caller's value, and fColorCount (our value) may
40 differ by up to 2. In the above example: 39 differ by up to 2. In the above example:
41 colorCount = 2 40 colorCount = 2
42 fColorCount = 4 41 fColorCount = 4
43 */ 42 */
44 fColorCount = colorCount; 43 fColorCount = desc.fCount;
45 // check if we need to add in dummy start and/or end position/colors 44 // check if we need to add in dummy start and/or end position/colors
46 bool dummyFirst = false; 45 bool dummyFirst = false;
47 bool dummyLast = false; 46 bool dummyLast = false;
48 if (pos) { 47 if (desc.fPos) {
49 dummyFirst = pos[0] != 0; 48 dummyFirst = desc.fPos[0] != 0;
50 dummyLast = pos[colorCount - 1] != SK_Scalar1; 49 dummyLast = desc.fPos[desc.fCount - 1] != SK_Scalar1;
51 fColorCount += dummyFirst + dummyLast; 50 fColorCount += dummyFirst + dummyLast;
52 } 51 }
53 52
54 if (fColorCount > kColorStorageCount) { 53 if (fColorCount > kColorStorageCount) {
55 size_t size = sizeof(SkColor) + sizeof(Rec); 54 size_t size = sizeof(SkColor) + sizeof(Rec);
56 fOrigColors = reinterpret_cast<SkColor*>( 55 fOrigColors = reinterpret_cast<SkColor*>(
57 sk_malloc_throw(size * fColorCount)); 56 sk_malloc_throw(size * fColorCount));
58 } 57 }
59 else { 58 else {
60 fOrigColors = fStorage; 59 fOrigColors = fStorage;
61 } 60 }
62 61
63 // Now copy over the colors, adding the dummies as needed 62 // Now copy over the colors, adding the dummies as needed
64 { 63 {
65 SkColor* origColors = fOrigColors; 64 SkColor* origColors = fOrigColors;
66 if (dummyFirst) { 65 if (dummyFirst) {
67 *origColors++ = colors[0]; 66 *origColors++ = desc.fColors[0];
68 } 67 }
69 memcpy(origColors, colors, colorCount * sizeof(SkColor)); 68 memcpy(origColors, desc.fColors, desc.fCount * sizeof(SkColor));
70 if (dummyLast) { 69 if (dummyLast) {
71 origColors += colorCount; 70 origColors += desc.fCount;
72 *origColors = colors[colorCount - 1]; 71 *origColors = desc.fColors[desc.fCount - 1];
73 } 72 }
74 } 73 }
75 74
76 fRecs = (Rec*)(fOrigColors + fColorCount); 75 fRecs = (Rec*)(fOrigColors + fColorCount);
77 if (fColorCount > 2) { 76 if (fColorCount > 2) {
78 Rec* recs = fRecs; 77 Rec* recs = fRecs;
79 recs->fPos = 0; 78 recs->fPos = 0;
80 // recs->fScale = 0; // unused; 79 // recs->fScale = 0; // unused;
81 recs += 1; 80 recs += 1;
82 if (pos) { 81 if (desc.fPos) {
83 /* We need to convert the user's array of relative positions into 82 /* We need to convert the user's array of relative positions into
84 fixed-point positions and scale factors. We need these results 83 fixed-point positions and scale factors. We need these results
85 to be strictly monotonic (no two values equal or out of order). 84 to be strictly monotonic (no two values equal or out of order).
86 Hence this complex loop that just jams a zero for the scale 85 Hence this complex loop that just jams a zero for the scale
87 value if it sees a segment out of order, and it assures that 86 value if it sees a segment out of order, and it assures that
88 we start at 0 and end at 1.0 87 we start at 0 and end at 1.0
89 */ 88 */
90 SkFixed prev = 0; 89 SkFixed prev = 0;
91 int startIndex = dummyFirst ? 0 : 1; 90 int startIndex = dummyFirst ? 0 : 1;
92 int count = colorCount + dummyLast; 91 int count = desc.fCount + dummyLast;
93 for (int i = startIndex; i < count; i++) { 92 for (int i = startIndex; i < count; i++) {
94 // force the last value to be 1.0 93 // force the last value to be 1.0
95 SkFixed curr; 94 SkFixed curr;
96 if (i == colorCount) { // we're really at the dummyLast 95 if (i == desc.fCount) { // we're really at the dummyLast
97 curr = SK_Fixed1; 96 curr = SK_Fixed1;
98 } else { 97 } else {
99 curr = SkScalarToFixed(pos[i]); 98 curr = SkScalarToFixed(desc.fPos[i]);
100 } 99 }
101 // pin curr withing range 100 // pin curr withing range
102 if (curr < 0) { 101 if (curr < 0) {
103 curr = 0; 102 curr = 0;
104 } else if (curr > SK_Fixed1) { 103 } else if (curr > SK_Fixed1) {
105 curr = SK_Fixed1; 104 curr = SK_Fixed1;
106 } 105 }
107 recs->fPos = curr; 106 recs->fPos = curr;
108 if (curr > prev) { 107 if (curr > prev) {
109 recs->fScale = (1 << 24) / (curr - prev); 108 recs->fScale = (1 << 24) / (curr - prev);
110 } else { 109 } else {
111 recs->fScale = 0; // ignore this segment 110 recs->fScale = 0; // ignore this segment
112 } 111 }
113 // get ready for the next value 112 // get ready for the next value
114 prev = curr; 113 prev = curr;
115 recs += 1; 114 recs += 1;
116 } 115 }
117 } else { // assume even distribution 116 } else { // assume even distribution
118 SkFixed dp = SK_Fixed1 / (colorCount - 1); 117 SkFixed dp = SK_Fixed1 / (desc.fCount - 1);
119 SkFixed p = dp; 118 SkFixed p = dp;
120 SkFixed scale = (colorCount - 1) << 8; // (1 << 24) / dp 119 SkFixed scale = (desc.fCount - 1) << 8; // (1 << 24) / dp
121 for (int i = 1; i < colorCount; i++) { 120 for (int i = 1; i < desc.fCount; i++) {
122 recs->fPos = p; 121 recs->fPos = p;
123 recs->fScale = scale; 122 recs->fScale = scale;
124 recs += 1; 123 recs += 1;
125 p += dp; 124 p += dp;
126 } 125 }
127 } 126 }
128 } 127 }
129 this->initCommon(); 128 this->initCommon();
130 } 129 }
131 130
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 SkColor tmp[2]; \ 632 SkColor tmp[2]; \
634 do { \ 633 do { \
635 if (1 == count) { \ 634 if (1 == count) { \
636 tmp[0] = tmp[1] = colors[0]; \ 635 tmp[0] = tmp[1] = colors[0]; \
637 colors = tmp; \ 636 colors = tmp; \
638 pos = NULL; \ 637 pos = NULL; \
639 count = 2; \ 638 count = 2; \
640 } \ 639 } \
641 } while (0) 640 } while (0)
642 641
642 static void desc_init(SkGradientShaderBase::Descriptor* desc,
643 const SkColor colors[],
644 const SkScalar pos[], int colorCount,
645 SkShader::TileMode mode,
646 SkUnitMapper* mapper) {
647 desc->fColors = colors;
648 desc->fPos = pos;
649 desc->fCount = colorCount;
650 desc->fTileMode = mode;
651 desc->fMapper = mapper;
652 }
653
643 SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2], 654 SkShader* SkGradientShader::CreateLinear(const SkPoint pts[2],
644 const SkColor colors[], 655 const SkColor colors[],
645 const SkScalar pos[], int colorCount, 656 const SkScalar pos[], int colorCount,
646 SkShader::TileMode mode, 657 SkShader::TileMode mode,
647 SkUnitMapper* mapper) { 658 SkUnitMapper* mapper) {
648 if (NULL == pts || NULL == colors || colorCount < 1) { 659 if (NULL == pts || NULL == colors || colorCount < 1) {
649 return NULL; 660 return NULL;
650 } 661 }
651 EXPAND_1_COLOR(colorCount); 662 EXPAND_1_COLOR(colorCount);
652 663
653 return SkNEW_ARGS(SkLinearGradient, 664 SkGradientShaderBase::Descriptor desc;
654 (pts, colors, pos, colorCount, mode, mapper)); 665 desc_init(&desc, colors, pos, colorCount, mode, mapper);
666 return SkNEW_ARGS(SkLinearGradient, (pts, desc));
655 } 667 }
656 668
657 SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius, 669 SkShader* SkGradientShader::CreateRadial(const SkPoint& center, SkScalar radius,
658 const SkColor colors[], 670 const SkColor colors[],
659 const SkScalar pos[], int colorCount, 671 const SkScalar pos[], int colorCount,
660 SkShader::TileMode mode, 672 SkShader::TileMode mode,
661 SkUnitMapper* mapper) { 673 SkUnitMapper* mapper) {
662 if (radius <= 0 || NULL == colors || colorCount < 1) { 674 if (radius <= 0 || NULL == colors || colorCount < 1) {
663 return NULL; 675 return NULL;
664 } 676 }
665 EXPAND_1_COLOR(colorCount); 677 EXPAND_1_COLOR(colorCount);
666 678
667 return SkNEW_ARGS(SkRadialGradient, 679 SkGradientShaderBase::Descriptor desc;
668 (center, radius, colors, pos, colorCount, mode, mapper)); 680 desc_init(&desc, colors, pos, colorCount, mode, mapper);
681 return SkNEW_ARGS(SkRadialGradient, (center, radius, desc));
669 } 682 }
670 683
671 SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start, 684 SkShader* SkGradientShader::CreateTwoPointRadial(const SkPoint& start,
672 SkScalar startRadius, 685 SkScalar startRadius,
673 const SkPoint& end, 686 const SkPoint& end,
674 SkScalar endRadius, 687 SkScalar endRadius,
675 const SkColor colors[], 688 const SkColor colors[],
676 const SkScalar pos[], 689 const SkScalar pos[],
677 int colorCount, 690 int colorCount,
678 SkShader::TileMode mode, 691 SkShader::TileMode mode,
679 SkUnitMapper* mapper) { 692 SkUnitMapper* mapper) {
680 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { 693 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) {
681 return NULL; 694 return NULL;
682 } 695 }
683 EXPAND_1_COLOR(colorCount); 696 EXPAND_1_COLOR(colorCount);
684 697
698 SkGradientShaderBase::Descriptor desc;
699 desc_init(&desc, colors, pos, colorCount, mode, mapper);
685 return SkNEW_ARGS(SkTwoPointRadialGradient, 700 return SkNEW_ARGS(SkTwoPointRadialGradient,
686 (start, startRadius, end, endRadius, colors, pos, 701 (start, startRadius, end, endRadius, desc));
687 colorCount, mode, mapper));
688 } 702 }
689 703
690 SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start, 704 SkShader* SkGradientShader::CreateTwoPointConical(const SkPoint& start,
691 SkScalar startRadius, 705 SkScalar startRadius,
692 const SkPoint& end, 706 const SkPoint& end,
693 SkScalar endRadius, 707 SkScalar endRadius,
694 const SkColor colors[], 708 const SkColor colors[],
695 const SkScalar pos[], 709 const SkScalar pos[],
696 int colorCount, 710 int colorCount,
697 SkShader::TileMode mode, 711 SkShader::TileMode mode,
698 SkUnitMapper* mapper) { 712 SkUnitMapper* mapper) {
699 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) { 713 if (startRadius < 0 || endRadius < 0 || NULL == colors || colorCount < 1) {
700 return NULL; 714 return NULL;
701 } 715 }
702 if (start == end && startRadius == endRadius) { 716 if (start == end && startRadius == endRadius) {
703 return SkNEW(SkEmptyShader); 717 return SkNEW(SkEmptyShader);
704 } 718 }
705 EXPAND_1_COLOR(colorCount); 719 EXPAND_1_COLOR(colorCount);
706 720
721 SkGradientShaderBase::Descriptor desc;
722 desc_init(&desc, colors, pos, colorCount, mode, mapper);
707 return SkNEW_ARGS(SkTwoPointConicalGradient, 723 return SkNEW_ARGS(SkTwoPointConicalGradient,
708 (start, startRadius, end, endRadius, colors, pos, 724 (start, startRadius, end, endRadius, desc));
709 colorCount, mode, mapper));
710 } 725 }
711 726
712 SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy, 727 SkShader* SkGradientShader::CreateSweep(SkScalar cx, SkScalar cy,
713 const SkColor colors[], 728 const SkColor colors[],
714 const SkScalar pos[], 729 const SkScalar pos[],
715 int count, SkUnitMapper* mapper) { 730 int colorCount, SkUnitMapper* mapper) {
716 if (NULL == colors || count < 1) { 731 if (NULL == colors || colorCount < 1) {
717 return NULL; 732 return NULL;
718 } 733 }
719 EXPAND_1_COLOR(count); 734 EXPAND_1_COLOR(colorCount);
720 735
721 return SkNEW_ARGS(SkSweepGradient, (cx, cy, colors, pos, count, mapper)); 736 SkGradientShaderBase::Descriptor desc;
737 desc_init(&desc, colors, pos, colorCount, SkShader::kClamp_TileMode, mapper) ;
738 return SkNEW_ARGS(SkSweepGradient, (cx, cy, desc));
722 } 739 }
723 740
724 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader) 741 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkGradientShader)
725 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient) 742 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLinearGradient)
726 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient) 743 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkRadialGradient)
727 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient) 744 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSweepGradient)
728 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointRadialGradient) 745 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointRadialGradient)
729 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient) 746 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkTwoPointConicalGradient)
730 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 747 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
731 748
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
891 (*stops)[i] = stop; 908 (*stops)[i] = stop;
892 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 909 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
893 } 910 }
894 } 911 }
895 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 912 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
896 913
897 return outColors; 914 return outColors;
898 } 915 }
899 916
900 #endif 917 #endif
OLDNEW
« no previous file with comments | « no previous file | src/effects/gradients/SkGradientShaderPriv.h » ('j') | src/effects/gradients/SkRadialGradient.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698