1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SkColor_DEFINED
9 #define SkColor_DEFINED
10 
11 #include "include/core/SkImageInfo.h"
12 #include "include/core/SkScalar.h"
13 #include "include/core/SkTypes.h"
14 
15 #include <array>
16 
17 /** \file SkColor.h
18 
19     Types, consts, functions, and macros for colors.
20 */
21 
22 /** 8-bit type for an alpha value. 255 is 100% opaque, zero is 100% transparent.
23 */
24 typedef uint8_t SkAlpha;
25 
26 /** 32-bit ARGB color value, unpremultiplied. Color components are always in
27     a known order. This is different from SkPMColor, which has its bytes in a configuration
28     dependent order, to match the format of kBGRA_8888_SkColorType bitmaps. SkColor
29     is the type used to specify colors in SkPaint and in gradients.
30 
31     Color that is premultiplied has the same component values as color
32     that is unpremultiplied if alpha is 255, fully opaque, although may have the
33     component values in a different order.
34 */
35 typedef uint32_t SkColor;
36 
37 /** Returns color value from 8-bit component values. Asserts if SK_DEBUG is defined
38     if a, r, g, or b exceed 255. Since color is unpremultiplied, a may be smaller
39     than the largest of r, g, and b.
40 
41     @param a  amount of alpha, from fully transparent (0) to fully opaque (255)
42     @param r  amount of red, from no red (0) to full red (255)
43     @param g  amount of green, from no green (0) to full green (255)
44     @param b  amount of blue, from no blue (0) to full blue (255)
45     @return   color and alpha, unpremultiplied
46 */
SkColorSetARGB(U8CPU a,U8CPU r,U8CPU g,U8CPU b)47 static constexpr inline SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b) {
48     return SkASSERT(a <= 255 && r <= 255 && g <= 255 && b <= 255),
49            (a << 24) | (r << 16) | (g << 8) | (b << 0);
50 }
51 
52 /** Returns color value from 8-bit component values, with alpha set
53     fully opaque to 255.
54 */
55 #define SkColorSetRGB(r, g, b)  SkColorSetARGB(0xFF, r, g, b)
56 
57 /** Returns alpha byte from color value.
58 */
59 #define SkColorGetA(color)      (((color) >> 24) & 0xFF)
60 
61 /** Returns red component of color, from zero to 255.
62 */
63 #define SkColorGetR(color)      (((color) >> 16) & 0xFF)
64 
65 /** Returns green component of color, from zero to 255.
66 */
67 #define SkColorGetG(color)      (((color) >>  8) & 0xFF)
68 
69 /** Returns blue component of color, from zero to 255.
70 */
71 #define SkColorGetB(color)      (((color) >>  0) & 0xFF)
72 
73 /** Returns unpremultiplied color with red, blue, and green set from c; and alpha set
74     from a. Alpha component of c is ignored and is replaced by a in result.
75 
76     @param c  packed RGB, eight bits per component
77     @param a  alpha: transparent at zero, fully opaque at 255
78     @return   color with transparency
79 */
SkColorSetA(SkColor c,U8CPU a)80 static constexpr inline SkColor SK_WARN_UNUSED_RESULT SkColorSetA(SkColor c, U8CPU a) {
81     return (c & 0x00FFFFFF) | (a << 24);
82 }
83 
84 /** Represents fully transparent SkAlpha value. SkAlpha ranges from zero,
85     fully transparent; to 255, fully opaque.
86 */
87 constexpr SkAlpha SK_AlphaTRANSPARENT = 0x00;
88 
89 /** Represents fully opaque SkAlpha value. SkAlpha ranges from zero,
90     fully transparent; to 255, fully opaque.
91 */
92 constexpr SkAlpha SK_AlphaOPAQUE      = 0xFF;
93 
94 /** Represents fully transparent SkColor. May be used to initialize a destination
95     containing a mask or a non-rectangular image.
96 */
97 constexpr SkColor SK_ColorTRANSPARENT = SkColorSetARGB(0x00, 0x00, 0x00, 0x00);
98 
99 /** Represents fully opaque black.
100 */
101 constexpr SkColor SK_ColorBLACK       = SkColorSetARGB(0xFF, 0x00, 0x00, 0x00);
102 
103 /** Represents fully opaque dark gray.
104     Note that SVG dark gray is equivalent to 0xFFA9A9A9.
105 */
106 constexpr SkColor SK_ColorDKGRAY      = SkColorSetARGB(0xFF, 0x44, 0x44, 0x44);
107 
108 /** Represents fully opaque gray.
109     Note that HTML gray is equivalent to 0xFF808080.
110 */
111 constexpr SkColor SK_ColorGRAY        = SkColorSetARGB(0xFF, 0x88, 0x88, 0x88);
112 
113 /** Represents fully opaque light gray. HTML silver is equivalent to 0xFFC0C0C0.
114     Note that SVG light gray is equivalent to 0xFFD3D3D3.
115 */
116 constexpr SkColor SK_ColorLTGRAY      = SkColorSetARGB(0xFF, 0xCC, 0xCC, 0xCC);
117 
118 /** Represents fully opaque white.
119 */
120 constexpr SkColor SK_ColorWHITE       = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0xFF);
121 
122 /** Represents fully opaque red.
123 */
124 constexpr SkColor SK_ColorRED         = SkColorSetARGB(0xFF, 0xFF, 0x00, 0x00);
125 
126 /** Represents fully opaque green. HTML lime is equivalent.
127     Note that HTML green is equivalent to 0xFF008000.
128 */
129 constexpr SkColor SK_ColorGREEN       = SkColorSetARGB(0xFF, 0x00, 0xFF, 0x00);
130 
131 /** Represents fully opaque blue.
132 */
133 constexpr SkColor SK_ColorBLUE        = SkColorSetARGB(0xFF, 0x00, 0x00, 0xFF);
134 
135 /** Represents fully opaque yellow.
136 */
137 constexpr SkColor SK_ColorYELLOW      = SkColorSetARGB(0xFF, 0xFF, 0xFF, 0x00);
138 
139 /** Represents fully opaque cyan. HTML aqua is equivalent.
140 */
141 constexpr SkColor SK_ColorCYAN        = SkColorSetARGB(0xFF, 0x00, 0xFF, 0xFF);
142 
143 /** Represents fully opaque magenta. HTML fuchsia is equivalent.
144 */
145 constexpr SkColor SK_ColorMAGENTA     = SkColorSetARGB(0xFF, 0xFF, 0x00, 0xFF);
146 
147 /** Converts RGB to its HSV components.
148     hsv[0] contains hsv hue, a value from zero to less than 360.
149     hsv[1] contains hsv saturation, a value from zero to one.
150     hsv[2] contains hsv value, a value from zero to one.
151 
152     @param red    red component value from zero to 255
153     @param green  green component value from zero to 255
154     @param blue   blue component value from zero to 255
155     @param hsv    three element array which holds the resulting HSV components
156 */
157 SK_API void SkRGBToHSV(U8CPU red, U8CPU green, U8CPU blue, SkScalar hsv[3]);
158 
159 /** Converts ARGB to its HSV components. Alpha in ARGB is ignored.
160     hsv[0] contains hsv hue, and is assigned a value from zero to less than 360.
161     hsv[1] contains hsv saturation, a value from zero to one.
162     hsv[2] contains hsv value, a value from zero to one.
163 
164     @param color  ARGB color to convert
165     @param hsv    three element array which holds the resulting HSV components
166 */
SkColorToHSV(SkColor color,SkScalar hsv[3])167 static inline void SkColorToHSV(SkColor color, SkScalar hsv[3]) {
168     SkRGBToHSV(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color), hsv);
169 }
170 
171 /** Converts HSV components to an ARGB color. Alpha is passed through unchanged.
172     hsv[0] represents hsv hue, an angle from zero to less than 360.
173     hsv[1] represents hsv saturation, and varies from zero to one.
174     hsv[2] represents hsv value, and varies from zero to one.
175 
176     Out of range hsv values are pinned.
177 
178     @param alpha  alpha component of the returned ARGB color
179     @param hsv    three element array which holds the input HSV components
180     @return       ARGB equivalent to HSV
181 */
182 SK_API SkColor SkHSVToColor(U8CPU alpha, const SkScalar hsv[3]);
183 
184 /** Converts HSV components to an ARGB color. Alpha is set to 255.
185     hsv[0] represents hsv hue, an angle from zero to less than 360.
186     hsv[1] represents hsv saturation, and varies from zero to one.
187     hsv[2] represents hsv value, and varies from zero to one.
188 
189     Out of range hsv values are pinned.
190 
191     @param hsv  three element array which holds the input HSV components
192     @return     RGB equivalent to HSV
193 */
SkHSVToColor(const SkScalar hsv[3])194 static inline SkColor SkHSVToColor(const SkScalar hsv[3]) {
195     return SkHSVToColor(0xFF, hsv);
196 }
197 
198 /** 32-bit ARGB color value, premultiplied. The byte order for this value is
199     configuration dependent, matching the format of kBGRA_8888_SkColorType bitmaps.
200     This is different from SkColor, which is unpremultiplied, and is always in the
201     same byte order.
202 */
203 typedef uint32_t SkPMColor;
204 
205 /** Returns a SkPMColor value from unpremultiplied 8-bit component values.
206 
207     @param a  amount of alpha, from fully transparent (0) to fully opaque (255)
208     @param r  amount of red, from no red (0) to full red (255)
209     @param g  amount of green, from no green (0) to full green (255)
210     @param b  amount of blue, from no blue (0) to full blue (255)
211     @return   premultiplied color
212 */
213 SK_API SkPMColor SkPreMultiplyARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
214 
215 /** Returns pmcolor closest to color c. Multiplies c RGB components by the c alpha,
216     and arranges the bytes to match the format of kN32_SkColorType.
217 
218     @param c  unpremultiplied ARGB color
219     @return   premultiplied color
220 */
221 SK_API SkPMColor SkPreMultiplyColor(SkColor c);
222 
223 /** \enum SkColorChannel
224     Describes different color channels one can manipulate
225 */
226 enum class SkColorChannel {
227     kR,  // the red channel
228     kG,  // the green channel
229     kB,  // the blue channel
230     kA,  // the alpha channel
231 
232     kLastEnum = kA,
233 };
234 
235 /** Used to represent the channels available in a color type or texture format as a mask. */
236 enum SkColorChannelFlag : uint32_t {
237     kRed_SkColorChannelFlag    = 1 << static_cast<uint32_t>(SkColorChannel::kR),
238     kGreen_SkColorChannelFlag  = 1 << static_cast<uint32_t>(SkColorChannel::kG),
239     kBlue_SkColorChannelFlag   = 1 << static_cast<uint32_t>(SkColorChannel::kB),
240     kAlpha_SkColorChannelFlag  = 1 << static_cast<uint32_t>(SkColorChannel::kA),
241     kGray_SkColorChannelFlag   = 0x10,
242     // Convenience values
243     kGrayAlpha_SkColorChannelFlags = kGray_SkColorChannelFlag | kAlpha_SkColorChannelFlag,
244     kRG_SkColorChannelFlags        = kRed_SkColorChannelFlag | kGreen_SkColorChannelFlag,
245     kRGB_SkColorChannelFlags       = kRG_SkColorChannelFlags | kBlue_SkColorChannelFlag,
246     kRGBA_SkColorChannelFlags      = kRGB_SkColorChannelFlags | kAlpha_SkColorChannelFlag,
247 };
248 static_assert(0 == (kGray_SkColorChannelFlag & kRGBA_SkColorChannelFlags), "bitfield conflict");
249 
250 /** \struct SkRGBA4f
251     RGBA color value, holding four floating point components. Color components are always in
252     a known order. kAT determines if the SkRGBA4f's R, G, and B components are premultiplied
253     by alpha or not.
254 
255     Skia's public API always uses unpremultiplied colors, which can be stored as
256     SkRGBA4f<kUnpremul_SkAlphaType>. For convenience, this type can also be referred to
257     as SkColor4f.
258 */
259 template <SkAlphaType kAT>
260 struct SkRGBA4f {
261     float fR;  //!< red component
262     float fG;  //!< green component
263     float fB;  //!< blue component
264     float fA;  //!< alpha component
265 
266     /** Compares SkRGBA4f with other, and returns true if all components are equal.
267 
268         @param other  SkRGBA4f to compare
269         @return       true if SkRGBA4f equals other
270     */
271     bool operator==(const SkRGBA4f& other) const {
272         return fA == other.fA && fR == other.fR && fG == other.fG && fB == other.fB;
273     }
274 
275     /** Compares SkRGBA4f with other, and returns true if not all components are equal.
276 
277         @param other  SkRGBA4f to compare
278         @return       true if SkRGBA4f is not equal to other
279     */
280     bool operator!=(const SkRGBA4f& other) const {
281         return !(*this == other);
282     }
283 
284     /** Returns SkRGBA4f multiplied by scale.
285 
286         @param scale  value to multiply by
287         @return       SkRGBA4f as (fR * scale, fG * scale, fB * scale, fA * scale)
288     */
289     SkRGBA4f operator*(float scale) const {
290         return { fR * scale, fG * scale, fB * scale, fA * scale };
291     }
292 
293     /** Returns SkRGBA4f multiplied component-wise by scale.
294 
295         @param scale  SkRGBA4f to multiply by
296         @return       SkRGBA4f as (fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA)
297     */
298     SkRGBA4f operator*(const SkRGBA4f& scale) const {
299         return { fR * scale.fR, fG * scale.fG, fB * scale.fB, fA * scale.fA };
300     }
301 
302     /** Returns a pointer to components of SkRGBA4f, for array access.
303 
304         @return       pointer to array [fR, fG, fB, fA]
305     */
vecSkRGBA4f306     const float* vec() const { return &fR; }
307 
308     /** Returns a pointer to components of SkRGBA4f, for array access.
309 
310         @return       pointer to array [fR, fG, fB, fA]
311     */
vecSkRGBA4f312     float* vec() { return &fR; }
313 
314     /** As a std::array<float, 4> */
arraySkRGBA4f315     std::array<float, 4> array() const { return {fR, fG, fB, fA}; }
316 
317     /** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.
318 
319         @param index  one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
320         @return       value corresponding to index
321     */
322     float operator[](int index) const {
323         SkASSERT(index >= 0 && index < 4);
324         return this->vec()[index];
325     }
326 
327     /** Returns one component. Asserts if index is out of range and SK_DEBUG is defined.
328 
329         @param index  one of: 0 (fR), 1 (fG), 2 (fB), 3 (fA)
330         @return       value corresponding to index
331     */
332     float& operator[](int index) {
333         SkASSERT(index >= 0 && index < 4);
334         return this->vec()[index];
335     }
336 
337     /** Returns true if SkRGBA4f is an opaque color. Asserts if fA is out of range and
338         SK_DEBUG is defined.
339 
340         @return       true if SkRGBA4f is opaque
341     */
isOpaqueSkRGBA4f342     bool isOpaque() const {
343         SkASSERT(fA <= 1.0f && fA >= 0.0f);
344         return fA == 1.0f;
345     }
346 
347     /** Returns true if all channels are in [0, 1]. */
fitsInBytesSkRGBA4f348     bool fitsInBytes() const {
349         SkASSERT(fA >= 0.0f && fA <= 1.0f);
350         return fR >= 0.0f && fR <= 1.0f &&
351                fG >= 0.0f && fG <= 1.0f &&
352                fB >= 0.0f && fB <= 1.0f;
353     }
354 
355     /** Returns closest SkRGBA4f to SkColor. Only allowed if SkRGBA4f is unpremultiplied.
356 
357         @param color   Color with Alpha, red, blue, and green components
358         @return        SkColor as SkRGBA4f
359 
360         example: https://fiddle.skia.org/c/@RGBA4f_FromColor
361     */
362     static SkRGBA4f FromColor(SkColor color);  // impl. depends on kAT
363 
364     /** Returns closest SkColor to SkRGBA4f. Only allowed if SkRGBA4f is unpremultiplied.
365 
366         @return       color as SkColor
367 
368         example: https://fiddle.skia.org/c/@RGBA4f_toSkColor
369     */
370     SkColor toSkColor() const;  // impl. depends on kAT
371 
372     /** Returns closest SkRGBA4f to SkPMColor. Only allowed if SkRGBA4f is premultiplied.
373 
374         @return        SkPMColor as SkRGBA4f
375     */
376     static SkRGBA4f FromPMColor(SkPMColor);  // impl. depends on kAT
377 
378     /** Returns SkRGBA4f premultiplied by alpha. Asserts at compile time if SkRGBA4f is
379         already premultiplied.
380 
381         @return       premultiplied color
382     */
premulSkRGBA4f383     SkRGBA4f<kPremul_SkAlphaType> premul() const {
384         static_assert(kAT == kUnpremul_SkAlphaType, "");
385         return { fR * fA, fG * fA, fB * fA, fA };
386     }
387 
388     /** Returns SkRGBA4f unpremultiplied by alpha. Asserts at compile time if SkRGBA4f is
389         already unpremultiplied.
390 
391         @return       unpremultiplied color
392     */
unpremulSkRGBA4f393     SkRGBA4f<kUnpremul_SkAlphaType> unpremul() const {
394         static_assert(kAT == kPremul_SkAlphaType, "");
395 
396         if (fA == 0.0f) {
397             return { 0, 0, 0, 0 };
398         } else {
399             float invAlpha = 1 / fA;
400             return { fR * invAlpha, fG * invAlpha, fB * invAlpha, fA };
401         }
402     }
403 
404     // This produces bytes in RGBA order (eg GrColor). Impl. is the same, regardless of kAT
405     uint32_t toBytes_RGBA() const;
406     static SkRGBA4f FromBytes_RGBA(uint32_t color);
407 
makeOpaqueSkRGBA4f408     SkRGBA4f makeOpaque() const {
409         return { fR, fG, fB, 1.0f };
410     }
411 };
412 
413 /** \struct SkColor4f
414     RGBA color value, holding four floating point components. Color components are always in
415     a known order, and are unpremultiplied.
416 
417     This is a specialization of SkRGBA4f. For details, @see SkRGBA4f.
418 */
419 using SkColor4f = SkRGBA4f<kUnpremul_SkAlphaType>;
420 
421 template <> SK_API SkColor4f SkColor4f::FromColor(SkColor);
422 template <> SK_API SkColor   SkColor4f::toSkColor() const;
423 
424 namespace SkColors {
425 constexpr SkColor4f kTransparent = {0, 0, 0, 0};
426 constexpr SkColor4f kBlack       = {0, 0, 0, 1};
427 constexpr SkColor4f kDkGray      = {0.25f, 0.25f, 0.25f, 1};
428 constexpr SkColor4f kGray        = {0.50f, 0.50f, 0.50f, 1};
429 constexpr SkColor4f kLtGray      = {0.75f, 0.75f, 0.75f, 1};
430 constexpr SkColor4f kWhite       = {1, 1, 1, 1};
431 constexpr SkColor4f kRed         = {1, 0, 0, 1};
432 constexpr SkColor4f kGreen       = {0, 1, 0, 1};
433 constexpr SkColor4f kBlue        = {0, 0, 1, 1};
434 constexpr SkColor4f kYellow      = {1, 1, 0, 1};
435 constexpr SkColor4f kCyan        = {0, 1, 1, 1};
436 constexpr SkColor4f kMagenta     = {1, 0, 1, 1};
437 }  // namespace SkColors
438 #endif
439