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