| 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 |