1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 @file:Suppress("NOTHING_TO_INLINE", "WRONG_ANNOTATION_TARGET_WITH_USE_SITE_TARGET_ON_TYPE") 18 19 package androidx.core.graphics 20 21 import android.graphics.Color 22 import android.graphics.ColorSpace 23 import androidx.annotation.ColorInt 24 import androidx.annotation.ColorLong 25 import androidx.annotation.RequiresApi 26 27 /** 28 * Returns the first component of the color. For instance, when the color model 29 * of the color is [android.graphics.ColorSpace.Model.RGB], the first component 30 * is "red". 31 * 32 * This method allows to use destructuring declarations when working with colors, 33 * for example: 34 * ``` 35 * val (red, green, blue) = myColor 36 * ``` 37 */ 38 @RequiresApi(26) 39 inline operator fun Color.component1() = getComponent(0) 40 41 /** 42 * Returns the second component of the color. For instance, when the color model 43 * of the color is [android.graphics.ColorSpace.Model.RGB], the second component 44 * is "green". 45 * 46 * This method allows to use destructuring declarations when working with colors, 47 * for example: 48 * ``` 49 * val (red, green, blue) = myColor 50 * ``` 51 */ 52 @RequiresApi(26) 53 inline operator fun Color.component2() = getComponent(1) 54 55 /** 56 * Returns the third component of the color. For instance, when the color model 57 * of the color is [android.graphics.ColorSpace.Model.RGB], the third component 58 * is "blue". 59 = * 60 * This method allows to use destructuring declarations when working with colors, 61 * for example: 62 * ``` 63 * val (red, green, blue) = myColor 64 * ``` 65 */ 66 @RequiresApi(26) 67 inline operator fun Color.component3() = getComponent(2) 68 69 /** 70 * Returns the fourth component of the color. For instance, when the color model 71 * of the color is [android.graphics.ColorSpace.Model.RGB], the fourth component 72 * is "alpha". 73 * 74 * This method allows to use destructuring declarations when working with colors, 75 * for example: 76 * ``` 77 * val (red, green, blue, alpha) = myColor 78 * ``` 79 */ 80 @RequiresApi(26) 81 inline operator fun Color.component4() = getComponent(3) 82 83 /** 84 * Composites two translucent colors together. More specifically, adds two colors using 85 * the [source over][android.graphics.PorterDuff.Mode.SRC_OVER] blending mode. The colors 86 * must not be pre-multiplied and the result is a non pre-multiplied color. 87 * 88 * If the two colors have different color spaces, the color in the right-hand part 89 * of the expression is converted to the color space of the color in left-hand part 90 * of the expression. 91 * 92 * The following example creates a purple color by blending opaque blue with 93 * semi-translucent red: 94 * 95 * ``` 96 * val purple = Color.valueOf(0f, 0f, 1f) + Color.valueOf(1f, 0f, 0f, 0.5f) 97 * ``` 98 * 99 * @throws IllegalArgumentException if the [color models][android.graphics.Color.getModel] 100 * of the colors do not match 101 */ 102 @RequiresApi(26) 103 operator fun Color.plus(c: Color): Color = ColorUtils.compositeColors(c, this) 104 105 /** 106 * Return the alpha component of a color int. This is equivalent to calling: 107 * ``` 108 * Color.alpha(myInt) 109 * ``` 110 */ 111 inline val @receiver:ColorInt Int.alpha get() = (this shr 24) and 0xff 112 113 /** 114 * Return the red component of a color int. This is equivalent to calling: 115 * ``` 116 * Color.red(myInt) 117 * ``` 118 */ 119 inline val @receiver:ColorInt Int.red get() = (this shr 16) and 0xff 120 121 /** 122 * Return the green component of a color int. This is equivalent to calling: 123 * ``` 124 * Color.green(myInt) 125 * ``` 126 */ 127 inline val @receiver:ColorInt Int.green get() = (this shr 8) and 0xff 128 129 /** 130 * Return the blue component of a color int. This is equivalent to calling: 131 * ``` 132 * Color.blue(myInt) 133 * ``` 134 */ 135 inline val @receiver:ColorInt Int.blue get() = this and 0xff 136 137 /** 138 * Return the alpha component of a color int. This is equivalent to calling: 139 * ``` 140 * Color.alpha(myInt) 141 * ``` 142 * 143 * This method allows to use destructuring declarations when working with colors, 144 * for example: 145 * ``` 146 * val (alpha, red, green, blue) = myColor 147 * ``` 148 */ 149 inline operator fun @receiver:ColorInt Int.component1() = (this shr 24) and 0xff 150 151 /** 152 * Return the red component of a color int. This is equivalent to calling: 153 * ``` 154 * Color.red(myInt) 155 * ``` 156 * 157 * This method allows to use destructuring declarations when working with colors, 158 * for example: 159 * ``` 160 * val (alpha, red, green, blue) = myColor 161 * ``` 162 */ 163 inline operator fun @receiver:ColorInt Int.component2() = (this shr 16) and 0xff 164 165 /** 166 * Return the green component of a color int. This is equivalent to calling: 167 * ``` 168 * Color.green(myInt) 169 * ``` 170 * 171 * This method allows to use destructuring declarations when working with colors, 172 * for example: 173 * ``` 174 * val (alpha, red, green, blue) = myColor 175 * ``` 176 */ 177 inline operator fun @receiver:ColorInt Int.component3() = (this shr 8) and 0xff 178 179 /** 180 * Return the blue component of a color int. This is equivalent to calling: 181 * ``` 182 * Color.blue(myInt) 183 * ``` 184 * 185 * This method allows to use destructuring declarations when working with colors, 186 * for example: 187 * ``` 188 * val (alpha, red, green, blue) = myColor 189 * ``` 190 */ 191 inline operator fun @receiver:ColorInt Int.component4() = this and 0xff 192 193 /** 194 * Returns the relative luminance of a color int, assuming sRGB encoding. 195 * Based on the formula for relative luminance defined in WCAG 2.0, 196 * W3C Recommendation 11 December 2008. 197 */ 198 @get:RequiresApi(26) 199 inline val @receiver:ColorInt Int.luminance get() = Color.luminance(this) 200 201 /** 202 * Creates a new [Color] instance from a color int. The resulting color 203 * is in the [sRGB][android.graphics.ColorSpace.Named.SRGB] color space. 204 */ 205 @RequiresApi(26) 206 inline fun @receiver:ColorInt Int.toColor(): Color = Color.valueOf(this) 207 208 /** 209 * Converts the specified ARGB [color int][Color] to an RGBA [color long][Color] 210 * in the [sRGB][android.graphics.ColorSpace.Named.SRGB] color space. 211 */ 212 @RequiresApi(26) 213 @ColorLong 214 inline fun @receiver:ColorInt Int.toColorLong() = Color.pack(this) 215 216 /** 217 * Returns the first component of the color. For instance, when the color model 218 * of the color is [android.graphics.ColorSpace.Model.RGB], the first component 219 * is "red". 220 * 221 * This method allows to use destructuring declarations when working with colors, 222 * for example: 223 * ``` 224 * val (red, green, blue, alpha) = myColorLong 225 * ``` 226 */ 227 @RequiresApi(26) 228 inline operator fun @receiver:ColorLong Long.component1() = Color.red(this) 229 230 /** 231 * Returns the second component of the color. For instance, when the color model 232 * of the color is [android.graphics.ColorSpace.Model.RGB], the second component 233 * is "green". 234 * 235 * This method allows to use destructuring declarations when working with colors, 236 * for example: 237 * ``` 238 * val (red, green, blue, alpha) = myColorLong 239 * ``` 240 */ 241 @RequiresApi(26) 242 inline operator fun @receiver:ColorLong Long.component2() = Color.green(this) 243 244 /** 245 * Returns the third component of the color. For instance, when the color model 246 * of the color is [android.graphics.ColorSpace.Model.RGB], the third component 247 * is "blue". 248 * 249 * This method allows to use destructuring declarations when working with colors, 250 * for example: 251 * ``` 252 * val (red, green, blue, alpha) = myColorLong 253 * ``` 254 */ 255 @RequiresApi(26) 256 inline operator fun @receiver:ColorLong Long.component3() = Color.blue(this) 257 258 /** 259 * Returns the fourth component of the color. For instance, when the color model 260 * of the color is [android.graphics.ColorSpace.Model.RGB], the fourth component 261 * is "alpha". 262 * 263 * This method allows to use destructuring declarations when working with colors, 264 * for example: 265 * ``` 266 * val (red, green, blue, alpha) = myColorLong 267 * ``` 268 */ 269 @RequiresApi(26) 270 inline operator fun @receiver:ColorLong Long.component4() = Color.alpha(this) 271 272 /** 273 * Return the alpha component of a color long. This is equivalent to calling: 274 * ``` 275 * Color.alpha(myLong) 276 * ``` 277 */ 278 @get:RequiresApi(26) 279 inline val @receiver:ColorLong Long.alpha get() = Color.alpha(this) 280 281 /** 282 * Return the red component of a color long. This is equivalent to calling: 283 * ``` 284 * Color.red(myLong) 285 * ``` 286 */ 287 @get:RequiresApi(26) 288 inline val @receiver:ColorLong Long.red get() = Color.red(this) 289 290 /** 291 * Return the green component of a color long. This is equivalent to calling: 292 * ``` 293 * Color.green(myLong) 294 * ``` 295 */ 296 @get:RequiresApi(26) 297 inline val @receiver:ColorLong Long.green get() = Color.green(this) 298 299 /** 300 * Return the blue component of a color long. This is equivalent to calling: 301 * ``` 302 * Color.blue(myLong) 303 * ``` 304 */ 305 @get:RequiresApi(26) 306 inline val @receiver:ColorLong Long.blue get() = Color.blue(this) 307 308 /** 309 * Returns the relative luminance of a color. Based on the formula for 310 * relative luminance defined in WCAG 2.0, W3C Recommendation 11 December 2008. 311 */ 312 @get:RequiresApi(26) 313 inline val @receiver:ColorLong Long.luminance get() = Color.luminance(this) 314 315 /** 316 * Creates a new [Color] instance from a [color long][Color]. 317 */ 318 @RequiresApi(26) 319 inline fun @receiver:ColorLong Long.toColor(): Color = Color.valueOf(this) 320 321 /** 322 * Converts the specified [color long][Color] to an ARGB [color int][Color]. 323 */ 324 @RequiresApi(26) 325 @ColorInt 326 inline fun @receiver:ColorLong Long.toColorInt() = Color.toArgb(this) 327 328 /** 329 * Indicates whether the color is in the [sRGB][android.graphics.ColorSpace.Named.SRGB] 330 * color space. 331 */ 332 @get:RequiresApi(26) 333 inline val @receiver:ColorLong Long.isSrgb get() = Color.isSrgb(this) 334 335 /** 336 * Indicates whether the color is in a [wide-gamut][android.graphics.ColorSpace] color space. 337 */ 338 @get:RequiresApi(26) 339 inline val @receiver:ColorLong Long.isWideGamut get() = Color.isWideGamut(this) 340 341 /** 342 * Returns the color space encoded in the specified color long. 343 */ 344 @get:RequiresApi(26) 345 inline val @receiver:ColorLong Long.colorSpace: ColorSpace get() = Color.colorSpace(this) 346 347 /** 348 * Return a corresponding [Int] color of this [String]. 349 * 350 * Supported formats are: 351 * ``` 352 * #RRGGBB 353 * #AARRGGBB 354 * ``` 355 * 356 * The following names are also accepted: "red", "blue", "green", "black", "white", 357 * "gray", "cyan", "magenta", "yellow", "lightgray", "darkgray", 358 * "grey", "lightgrey", "darkgrey", "aqua", "fuchsia", "lime", 359 * "maroon", "navy", "olive", "purple", "silver", "teal". 360 * 361 * @throws IllegalArgumentException if this [String] cannot be parsed. 362 */ 363 @ColorInt 364 inline fun String.toColorInt(): Int = Color.parseColor(this) 365