• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libs/graphics/sgl/SkColor.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 "SkColor.h"
19 #include "SkColorPriv.h"
20 
SkPreMultiplyARGB(U8CPU a,U8CPU r,U8CPU g,U8CPU b)21 SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
22     if (a != 255) {
23 #if 0
24         unsigned scale = SkAlpha255To256(a);
25         r = SkAlphaMul(r, scale);
26         g = SkAlphaMul(g, scale);
27         b = SkAlphaMul(b, scale);
28 #else
29         r = SkMulDiv255Round(r, a);
30         g = SkMulDiv255Round(g, a);
31         b = SkMulDiv255Round(b, a);
32 #endif
33     }
34     return SkPackARGB32(a, r, g, b);
35 }
36 
SkPreMultiplyColor(SkColor c)37 SkPMColor SkPreMultiplyColor(SkColor c) {
38     unsigned a = SkColorGetA(c);
39     unsigned r = SkColorGetR(c);
40     unsigned g = SkColorGetG(c);
41     unsigned b = SkColorGetB(c);
42 
43     return SkPreMultiplyARGB(a, r, g, b);
44 }
45 
46 //////////////////////////////////////////////////////////////////////////////////////////////
47 
ByteToScalar(U8CPU x)48 static inline SkScalar ByteToScalar(U8CPU x) {
49     SkASSERT(x <= 255);
50     return SkIntToScalar(x) / 255;
51 }
52 
ByteDivToScalar(int numer,U8CPU denom)53 static inline SkScalar ByteDivToScalar(int numer, U8CPU denom) {
54     // cast to keep the answer signed
55     return SkIntToScalar(numer) / (int)denom;
56 }
57 
SkRGBToHSV(U8CPU r,U8CPU g,U8CPU b,SkScalar hsv[3])58 void SkRGBToHSV(U8CPU r, U8CPU g, U8CPU b, SkScalar hsv[3]) {
59     SkASSERT(hsv);
60 
61     unsigned min = SkMin32(r, SkMin32(g, b));
62     unsigned max = SkMax32(r, SkMax32(g, b));
63     unsigned delta = max - min;
64 
65     SkScalar v = ByteToScalar(max);
66     SkASSERT(v >= 0 && v <= SK_Scalar1);
67 
68     if (0 == delta) { // we're a shade of gray
69         hsv[0] = 0;
70         hsv[1] = 0;
71         hsv[2] = v;
72         return;
73     }
74 
75     SkScalar s = ByteDivToScalar(delta, max);
76     SkASSERT(s >= 0 && s <= SK_Scalar1);
77 
78     SkScalar h;
79     if (r == max) {
80         h = ByteDivToScalar(g - b, delta);
81     } else if (g == max) {
82         h = SkIntToScalar(2) + ByteDivToScalar(b - r, delta);
83     } else { // b == max
84         h = SkIntToScalar(4) + ByteDivToScalar(r - g, delta);
85     }
86 
87     h *= 60;
88     if (h < 0) {
89         h += SkIntToScalar(360);
90     }
91     SkASSERT(h >= 0 && h < SkIntToScalar(360));
92 
93     hsv[0] = h;
94     hsv[1] = s;
95     hsv[2] = v;
96 }
97 
UnitScalarToByte(SkScalar x)98 static inline U8CPU UnitScalarToByte(SkScalar x) {
99     if (x < 0) {
100         return 0;
101     }
102     if (x >= SK_Scalar1) {
103         return 255;
104     }
105     return SkScalarToFixed(x) >> 8;
106 }
107 
SkHSVToColor(U8CPU a,const SkScalar hsv[3])108 SkColor SkHSVToColor(U8CPU a, const SkScalar hsv[3]) {
109     SkASSERT(hsv);
110 
111     U8CPU s = UnitScalarToByte(hsv[1]);
112     U8CPU v = UnitScalarToByte(hsv[2]);
113 
114     if (0 == s) { // shade of gray
115         return SkColorSetARGB(a, v, v, v);
116     }
117     SkFixed hx = (hsv[0] < 0 || hsv[0] >= SkIntToScalar(360)) ? 0 : SkScalarToFixed(hsv[0]/60);
118     SkFixed f = hx & 0xFFFF;
119 
120     unsigned v_scale = SkAlpha255To256(v);
121     unsigned p = SkAlphaMul(255 - s, v_scale);
122     unsigned q = SkAlphaMul(255 - (s * f >> 16), v_scale);
123     unsigned t = SkAlphaMul(255 - (s * (SK_Fixed1 - f) >> 16), v_scale);
124 
125     unsigned r, g, b;
126 
127     SkASSERT((unsigned)(hx >> 16) < 6);
128     switch (hx >> 16) {
129         case 0: r = v; g = t; b = p; break;
130         case 1: r = q; g = v; b = p; break;
131         case 2: r = p; g = v; b = t; break;
132         case 3: r = p; g = q; b = v; break;
133         case 4: r = t;  g = p; b = v; break;
134         default: r = v; g = p; b = q; break;
135     }
136     return SkColorSetARGB(a, r, g, b);
137 }
138 
139