1
2 /*
3 * Copyright 2006 The Android Open Source Project
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9
10 #include "SkDrawGradient.h"
11 #include "SkAnimateMaker.h"
12 #include "SkAnimatorScript.h"
13 #include "SkGradientShader.h"
14
15 #if SK_USE_CONDENSED_INFO == 0
16
17 const SkMemberInfo SkDrawGradient::fInfo[] = {
18 SK_MEMBER_INHERITED,
19 SK_MEMBER_ARRAY(offsets, Float),
20 SK_MEMBER(unitMapper, String)
21 };
22
23 #endif
24
25 DEFINE_GET_MEMBER(SkDrawGradient);
26
SkDrawGradient()27 SkDrawGradient::SkDrawGradient() {
28 }
29
~SkDrawGradient()30 SkDrawGradient::~SkDrawGradient() {
31 for (int index = 0; index < fDrawColors.count(); index++)
32 delete fDrawColors[index];
33 }
34
addChild(SkAnimateMaker &,SkDisplayable * child)35 bool SkDrawGradient::addChild(SkAnimateMaker& , SkDisplayable* child) {
36 SkASSERT(child);
37 if (child->isColor()) {
38 SkDrawColor* color = (SkDrawColor*) child;
39 *fDrawColors.append() = color;
40 return true;
41 }
42 return false;
43 }
44
addPrelude()45 int SkDrawGradient::addPrelude() {
46 int count = fDrawColors.count();
47 fColors.setCount(count);
48 for (int index = 0; index < count; index++)
49 fColors[index] = fDrawColors[index]->color;
50 return count;
51 }
52
53 #ifdef SK_DUMP_ENABLED
dumpRest(SkAnimateMaker * maker)54 void SkDrawGradient::dumpRest(SkAnimateMaker* maker) {
55 dumpAttrs(maker);
56 //can a gradient have no colors?
57 bool closedYet = false;
58 SkDisplayList::fIndent += 4;
59 for (SkDrawColor** ptr = fDrawColors.begin(); ptr < fDrawColors.end(); ptr++) {
60 if (closedYet == false) {
61 SkDebugf(">\n");
62 closedYet = true;
63 }
64 SkDrawColor* color = *ptr;
65 color->dump(maker);
66 }
67 SkDisplayList::fIndent -= 4;
68 dumpChildren(maker, closedYet); //dumps the matrix if it has one
69 }
70 #endif
71
onEndElement(SkAnimateMaker & maker)72 void SkDrawGradient::onEndElement(SkAnimateMaker& maker) {
73 if (offsets.count() != 0) {
74 if (offsets.count() != fDrawColors.count()) {
75 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsDontMatchColors);
76 return;
77 }
78 if (offsets[0] != 0) {
79 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustStartWithZero);
80 return;
81 }
82 if (offsets[offsets.count()-1] != SK_Scalar1) {
83 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustEndWithOne);
84 return;
85 }
86 for (int i = 1; i < offsets.count(); i++) {
87 if (offsets[i] <= offsets[i-1]) {
88 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustIncrease);
89 return;
90 }
91 if (offsets[i] > SK_Scalar1) {
92 maker.setErrorCode(SkDisplayXMLParserError::kGradientOffsetsMustBeNoMoreThanOne);
93 return;
94 }
95 }
96 }
97 INHERITED::onEndElement(maker);
98 }
99
100 #if SK_USE_CONDENSED_INFO == 0
101
102 const SkMemberInfo SkDrawLinearGradient::fInfo[] = {
103 SK_MEMBER_INHERITED,
104 SK_MEMBER_ARRAY(points, Float),
105 };
106
107 #endif
108
109 DEFINE_GET_MEMBER(SkDrawLinearGradient);
110
SkDrawLinearGradient()111 SkDrawLinearGradient::SkDrawLinearGradient() {
112 }
113
onEndElement(SkAnimateMaker & maker)114 void SkDrawLinearGradient::onEndElement(SkAnimateMaker& maker)
115 {
116 if (points.count() != 4)
117 maker.setErrorCode(SkDisplayXMLParserError::kGradientPointsLengthMustBeFour);
118 INHERITED::onEndElement(maker);
119 }
120
121 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)122 void SkDrawLinearGradient::dump(SkAnimateMaker* maker) {
123 dumpBase(maker);
124 dumpRest(maker);
125 }
126 #endif
127
getShader()128 SkShader* SkDrawLinearGradient::getShader() {
129 if (addPrelude() == 0 || points.count() != 4)
130 return nullptr;
131 SkShader* shader = SkGradientShader::CreateLinear((SkPoint*)points.begin(),
132 fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode,
133 0, getMatrix());
134 SkAutoTDelete<SkShader> autoDel(shader);
135 (void)autoDel.detach();
136 return shader;
137 }
138
139
140 #if SK_USE_CONDENSED_INFO == 0
141
142 const SkMemberInfo SkDrawRadialGradient::fInfo[] = {
143 SK_MEMBER_INHERITED,
144 SK_MEMBER(center, Point),
145 SK_MEMBER(radius, Float)
146 };
147
148 #endif
149
150 DEFINE_GET_MEMBER(SkDrawRadialGradient);
151
SkDrawRadialGradient()152 SkDrawRadialGradient::SkDrawRadialGradient() : radius(0) {
153 center.set(0, 0);
154 }
155
156 #ifdef SK_DUMP_ENABLED
dump(SkAnimateMaker * maker)157 void SkDrawRadialGradient::dump(SkAnimateMaker* maker) {
158 dumpBase(maker);
159 dumpRest(maker);
160 }
161 #endif
162
getShader()163 SkShader* SkDrawRadialGradient::getShader() {
164 if (addPrelude() == 0)
165 return nullptr;
166 SkShader* shader = SkGradientShader::CreateRadial(center,
167 radius, fColors.begin(), offsets.begin(), fColors.count(), (SkShader::TileMode) tileMode,
168 0, getMatrix());
169 SkAutoTDelete<SkShader> autoDel(shader);
170 (void)autoDel.detach();
171 return shader;
172 }
173