OLD | NEW |
| (Empty) |
1 /* libs/graphics/animator/SkDrawColor.cpp | |
2 ** | |
3 ** Copyright 2006, The Android Open Source Project | |
4 ** | |
5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 ** you may not use this file except in compliance with the License. | |
7 ** You may obtain a copy of the License at | |
8 ** | |
9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 ** | |
11 ** Unless required by applicable law or agreed to in writing, software | |
12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 ** See the License for the specific language governing permissions and | |
15 ** limitations under the License. | |
16 */ | |
17 | |
18 #include "SkDrawColor.h" | |
19 #ifdef SK_DEBUG | |
20 #include "SkDisplayList.h" | |
21 #endif | |
22 #include "SkDrawPaint.h" | |
23 #include "SkParse.h" | |
24 #include "SkScript.h" | |
25 | |
26 enum HSV_Choice { | |
27 kGetHue, | |
28 kGetSaturation, | |
29 kGetValue | |
30 }; | |
31 | |
32 static SkScalar RGB_to_HSV(SkColor color, HSV_Choice choice) { | |
33 SkScalar red = SkIntToScalar(SkColorGetR(color)); | |
34 SkScalar green = SkIntToScalar(SkColorGetG(color)); | |
35 SkScalar blue = SkIntToScalar(SkColorGetB(color)); | |
36 SkScalar min = SkMinScalar(SkMinScalar(red, green), blue); | |
37 SkScalar value = SkMaxScalar(SkMaxScalar(red, green), blue); | |
38 if (choice == kGetValue) | |
39 return value/255; | |
40 SkScalar delta = value - min; | |
41 SkScalar saturation = value == 0 ? 0 : SkScalarDiv(delta, value); | |
42 if (choice == kGetSaturation) | |
43 return saturation; | |
44 SkScalar hue; | |
45 if (saturation == 0) | |
46 hue = 0; | |
47 else { | |
48 SkScalar part60 = SkScalarDiv(60 * SK_Scalar1, delta); | |
49 if (red == value) { | |
50 hue = SkScalarMul(green - blue, part60); | |
51 if (hue < 0) | |
52 hue += 360 * SK_Scalar1; | |
53 } | |
54 else if (green == value) | |
55 hue = 120 * SK_Scalar1 + SkScalarMul(blue - red, part60); | |
56 else // blue == value | |
57 hue = 240 * SK_Scalar1 + SkScalarMul(red - green, part60); | |
58 } | |
59 SkASSERT(choice == kGetHue); | |
60 return hue; | |
61 } | |
62 | |
63 #if defined _WIN32 && _MSC_VER >= 1300 // disable 'red', etc. may be used witho
ut having been initialized | |
64 #pragma warning ( push ) | |
65 #pragma warning ( disable : 4701 ) | |
66 #endif | |
67 | |
68 static SkColor HSV_to_RGB(SkColor color, HSV_Choice choice, SkScalar hsv) { | |
69 SkScalar hue = choice == kGetHue ? hsv : RGB_to_HSV(color, kGetHue); | |
70 SkScalar saturation = choice == kGetSaturation ? hsv : RGB_to_HSV(color, kGe
tSaturation); | |
71 SkScalar value = choice == kGetValue ? hsv : RGB_to_HSV(color, kGetValue); | |
72 value *= 255; | |
73 SkScalar red SK_INIT_TO_AVOID_WARNING; | |
74 SkScalar green SK_INIT_TO_AVOID_WARNING; | |
75 SkScalar blue SK_INIT_TO_AVOID_WARNING; | |
76 if (saturation == 0) // color is on black-and-white center line | |
77 red = green = blue = value; | |
78 else { | |
79 //SkScalar fraction = SkScalarMod(hue, 60 * SK_Scalar1); | |
80 int sextant = SkScalarFloor(hue / 60); | |
81 SkScalar fraction = hue / 60 - SkIntToScalar(sextant); | |
82 SkScalar p = SkScalarMul(value , SK_Scalar1 - saturation); | |
83 SkScalar q = SkScalarMul(value, SK_Scalar1 - SkScalarMul(saturation, fra
ction)); | |
84 SkScalar t = SkScalarMul(value, SK_Scalar1 - | |
85 SkScalarMul(saturation, SK_Scalar1 - fraction)); | |
86 switch (sextant % 6) { | |
87 case 0: red = value; green = t; blue = p; break; | |
88 case 1: red = q; green = value; blue = p; break; | |
89 case 2: red = p; green = value; blue = t; break; | |
90 case 3: red = p; green = q; blue = value; break; | |
91 case 4: red = t; green = p; blue = value; break; | |
92 case 5: red = value; green = p; blue = q; break; | |
93 } | |
94 } | |
95 //used to say SkToU8((U8CPU) red) etc | |
96 return SkColorSetARGB(SkColorGetA(color), SkScalarRound(red), | |
97 SkScalarRound(green), SkScalarRound(blue)); | |
98 } | |
99 | |
100 #if defined _WIN32 && _MSC_VER >= 1300 | |
101 #pragma warning ( pop ) | |
102 #endif | |
103 | |
104 enum SkDrawColor_Properties { | |
105 SK_PROPERTY(alpha), | |
106 SK_PROPERTY(blue), | |
107 SK_PROPERTY(green), | |
108 SK_PROPERTY(hue), | |
109 SK_PROPERTY(red), | |
110 SK_PROPERTY(saturation), | |
111 SK_PROPERTY(value) | |
112 }; | |
113 | |
114 #if SK_USE_CONDENSED_INFO == 0 | |
115 | |
116 const SkMemberInfo SkDrawColor::fInfo[] = { | |
117 SK_MEMBER_PROPERTY(alpha, Float), | |
118 SK_MEMBER_PROPERTY(blue, Float), | |
119 SK_MEMBER(color, ARGB), | |
120 SK_MEMBER_PROPERTY(green, Float), | |
121 SK_MEMBER_PROPERTY(hue, Float), | |
122 SK_MEMBER_PROPERTY(red, Float), | |
123 SK_MEMBER_PROPERTY(saturation, Float), | |
124 SK_MEMBER_PROPERTY(value, Float), | |
125 }; | |
126 | |
127 #endif | |
128 | |
129 DEFINE_GET_MEMBER(SkDrawColor); | |
130 | |
131 SkDrawColor::SkDrawColor() : fDirty(false) { | |
132 color = SK_ColorBLACK; | |
133 fHue = fSaturation = fValue = SK_ScalarNaN; | |
134 } | |
135 | |
136 bool SkDrawColor::add() { | |
137 if (fPaint->color != NULL) | |
138 return true; // error (probably color in paint as attribute as well) | |
139 fPaint->color = this; | |
140 fPaint->fOwnsColor = true; | |
141 return false; | |
142 } | |
143 | |
144 SkDisplayable* SkDrawColor::deepCopy(SkAnimateMaker* maker) { | |
145 SkDrawColor* copy = new SkDrawColor(); | |
146 copy->color = color; | |
147 copy->fHue = fHue; | |
148 copy->fSaturation = fSaturation; | |
149 copy->fValue = fValue; | |
150 copy->fDirty = fDirty; | |
151 return copy; | |
152 } | |
153 | |
154 void SkDrawColor::dirty(){ | |
155 fDirty = true; | |
156 } | |
157 | |
158 #ifdef SK_DUMP_ENABLED | |
159 void SkDrawColor::dump(SkAnimateMaker* maker) { | |
160 dumpBase(maker); | |
161 SkDebugf("alpha=\"%d\" red=\"%d\" green=\"%d\" blue=\"%d\" />\n", | |
162 SkColorGetA(color)/255, SkColorGetR(color), | |
163 SkColorGetG(color), SkColorGetB(color)); | |
164 } | |
165 #endif | |
166 | |
167 SkColor SkDrawColor::getColor() { | |
168 if (fDirty) { | |
169 if (SkScalarIsNaN(fValue) == false) | |
170 color = HSV_to_RGB(color, kGetValue, fValue); | |
171 if (SkScalarIsNaN(fSaturation) == false) | |
172 color = HSV_to_RGB(color, kGetSaturation, fSaturation); | |
173 if (SkScalarIsNaN(fHue) == false) | |
174 color = HSV_to_RGB(color, kGetHue, fHue); | |
175 fDirty = false; | |
176 } | |
177 return color; | |
178 } | |
179 | |
180 SkDisplayable* SkDrawColor::getParent() const { | |
181 return fPaint; | |
182 } | |
183 | |
184 bool SkDrawColor::getProperty(int index, SkScriptValue* value) const { | |
185 value->fType = SkType_Float; | |
186 SkScalar result; | |
187 switch(index) { | |
188 case SK_PROPERTY(alpha): | |
189 result = SkIntToScalar(SkColorGetA(color)) / 255; | |
190 break; | |
191 case SK_PROPERTY(blue): | |
192 result = SkIntToScalar(SkColorGetB(color)); | |
193 break; | |
194 case SK_PROPERTY(green): | |
195 result = SkIntToScalar(SkColorGetG(color)); | |
196 break; | |
197 case SK_PROPERTY(hue): | |
198 result = RGB_to_HSV(color, kGetHue); | |
199 break; | |
200 case SK_PROPERTY(red): | |
201 result = SkIntToScalar(SkColorGetR(color)); | |
202 break; | |
203 case SK_PROPERTY(saturation): | |
204 result = RGB_to_HSV(color, kGetSaturation); | |
205 break; | |
206 case SK_PROPERTY(value): | |
207 result = RGB_to_HSV(color, kGetValue); | |
208 break; | |
209 default: | |
210 SkASSERT(0); | |
211 return false; | |
212 } | |
213 value->fOperand.fScalar = result; | |
214 return true; | |
215 } | |
216 | |
217 void SkDrawColor::onEndElement(SkAnimateMaker& maker){ | |
218 fDirty = true; | |
219 } | |
220 | |
221 bool SkDrawColor::setParent(SkDisplayable* parent) { | |
222 SkASSERT(parent != NULL); | |
223 if (parent->getType() == SkType_LinearGradient || parent->getType() == SkTyp
e_RadialGradient) | |
224 return false; | |
225 if (parent->isPaint() == false) | |
226 return true; | |
227 fPaint = (SkDrawPaint*) parent; | |
228 return false; | |
229 } | |
230 | |
231 bool SkDrawColor::setProperty(int index, SkScriptValue& value) { | |
232 SkASSERT(value.fType == SkType_Float); | |
233 SkScalar scalar = value.fOperand.fScalar; | |
234 switch (index) { | |
235 case SK_PROPERTY(alpha): | |
236 uint8_t alpha; | |
237 #ifdef SK_SCALAR_IS_FLOAT | |
238 alpha = scalar == SK_Scalar1 ? 255 : SkToU8((U8CPU) (scalar * 256)); | |
239 #else | |
240 alpha = SkToU8((scalar - (scalar >= SK_ScalarHalf)) >> 8); | |
241 #endif | |
242 color = SkColorSetARGB(alpha, SkColorGetR(color), | |
243 SkColorGetG(color), SkColorGetB(color)); | |
244 break; | |
245 case SK_PROPERTY(blue): | |
246 scalar = SkScalarClampMax(scalar, 255 * SK_Scalar1); | |
247 color = SkColorSetARGB(SkColorGetA(color), SkColorGetR(color), | |
248 SkColorGetG(color), SkToU8((U8CPU) scalar)); | |
249 break; | |
250 case SK_PROPERTY(green): | |
251 scalar = SkScalarClampMax(scalar, 255 * SK_Scalar1); | |
252 color = SkColorSetARGB(SkColorGetA(color), SkColorGetR(color), | |
253 SkToU8((U8CPU) scalar), SkColorGetB(color)); | |
254 break; | |
255 case SK_PROPERTY(hue): | |
256 fHue = scalar;//RGB_to_HSV(color, kGetHue); | |
257 fDirty = true; | |
258 break; | |
259 case SK_PROPERTY(red): | |
260 scalar = SkScalarClampMax(scalar, 255 * SK_Scalar1); | |
261 color = SkColorSetARGB(SkColorGetA(color), SkToU8((U8CPU) scalar), | |
262 SkColorGetG(color), SkColorGetB(color)); | |
263 break; | |
264 case SK_PROPERTY(saturation): | |
265 fSaturation = scalar;//RGB_to_HSV(color, kGetSaturation); | |
266 fDirty = true; | |
267 break; | |
268 case SK_PROPERTY(value): | |
269 fValue = scalar;//RGB_to_HSV(color, kGetValue); | |
270 fDirty = true; | |
271 break; | |
272 default: | |
273 SkASSERT(0); | |
274 return false; | |
275 } | |
276 return true; | |
277 } | |
278 | |
OLD | NEW |