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