1 /* 2 * Copyright (C) 2019 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 package androidx.core.graphics; 18 19 import android.os.Build; 20 21 import androidx.annotation.RequiresApi; 22 23 /** 24 * Compat version of {@link android.graphics.BlendMode}, usages of {@link BlendModeCompat} will 25 * map to {@link android.graphics.PorterDuff.Mode} wherever possible 26 */ 27 public enum BlendModeCompat { 28 29 /** 30 * {@usesMathJax} 31 * 32 * Destination pixels covered by the source are cleared to 0. 33 * 34 * <p>\(\alpha_{out} = 0\)</p> 35 * <p>\(C_{out} = 0\)</p> 36 */ 37 CLEAR, 38 39 /** 40 * {@usesMathJax} 41 * 42 * The source pixels replace the destination pixels. 43 * 44 * <p>\(\alpha_{out} = \alpha_{src}\)</p> 45 * <p>\(C_{out} = C_{src}\)</p> 46 */ 47 SRC, 48 49 /** 50 * {@usesMathJax} 51 * 52 * The source pixels are discarded, leaving the destination intact. 53 * 54 * <p>\(\alpha_{out} = \alpha_{dst}\)</p> 55 * <p>\(C_{out} = C_{dst}\)</p> 56 */ 57 DST, 58 59 /** 60 * {@usesMathJax} 61 * 62 * The source pixels are drawn over the destination pixels. 63 * 64 * <p>\(\alpha_{out} = \alpha_{src} + (1 - \alpha_{src}) * \alpha_{dst}\)</p> 65 * <p>\(C_{out} = C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p> 66 */ 67 SRC_OVER, 68 69 /** 70 * {@usesMathJax} 71 * 72 * The source pixels are drawn behind the destination pixels. 73 * 74 * <p>\(\alpha_{out} = \alpha_{dst} + (1 - \alpha_{dst}) * \alpha_{src}\)</p> 75 * <p>\(C_{out} = C_{dst} + (1 - \alpha_{dst}) * C_{src}\)</p> 76 */ 77 DST_OVER, 78 79 /** 80 * {@usesMathJax} 81 * 82 * Keeps the source pixels that cover the destination pixels, 83 * discards the remaining source and destination pixels. 84 * 85 * <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p> 86 * <p>\(C_{out} = C_{src} * \alpha_{dst}\)</p> 87 */ 88 SRC_IN, 89 90 /** 91 * {@usesMathJax} 92 * 93 * Keeps the destination pixels that cover source pixels, 94 * discards the remaining source and destination pixels. 95 * <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p> 96 * <p>\(C_{out} = C_{dst} * \alpha_{src}\)</p> 97 */ 98 DST_IN, 99 100 /** 101 * {@usesMathJax} 102 * 103 * Keeps the source pixels that do not cover destination pixels. 104 * Discards source pixels that cover destination pixels. Discards all 105 * destination pixels. 106 * 107 * <p>\(\alpha_{out} = (1 - \alpha_{dst}) * \alpha_{src}\)</p> 108 * <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src}\)</p> 109 */ 110 SRC_OUT, 111 112 /** 113 * {@usesMathJax} 114 * 115 * Keeps the destination pixels that are not covered by source pixels. 116 * Discards destination pixels that are covered by source pixels. Discards all 117 * source pixels. 118 * 119 * <p>\(\alpha_{out} = (1 - \alpha_{src}) * \alpha_{dst}\)</p> 120 * <p>\(C_{out} = (1 - \alpha_{src}) * C_{dst}\)</p> 121 */ 122 DST_OUT, 123 124 /** 125 * {@usesMathJax} 126 * 127 * Discards the source pixels that do not cover destination pixels. 128 * Draws remaining source pixels over destination pixels. 129 * 130 * <p>\(\alpha_{out} = \alpha_{dst}\)</p> 131 * <p>\(C_{out} = \alpha_{dst} * C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p> 132 */ 133 SRC_ATOP, 134 135 /** 136 * {@usesMathJax} 137 * 138 * Discards the destination pixels that are not covered by source pixels. 139 * Draws remaining destination pixels over source pixels. 140 * 141 * <p>\(\alpha_{out} = \alpha_{src}\)</p> 142 * <p>\(C_{out} = \alpha_{src} * C_{dst} + (1 - \alpha_{dst}) * C_{src}\)</p> 143 */ 144 DST_ATOP, 145 146 /** 147 * {@usesMathJax} 148 * 149 * Discards the source and destination pixels where source pixels 150 * cover destination pixels. Draws remaining source pixels. 151 * 152 * <p> 153 * \(\alpha_{out} = (1 - \alpha_{dst}) * \alpha_{src} + (1 - \alpha_{src}) * \alpha_{dst}\) 154 * </p> 155 * <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p> 156 */ 157 XOR, 158 159 /** 160 * {@usesMathJax} 161 * 162 * Adds the source pixels to the destination pixels and saturates 163 * the result. 164 * 165 * <p>\(\alpha_{out} = max(0, min(\alpha_{src} + \alpha_{dst}, 1))\)</p> 166 * <p>\(C_{out} = max(0, min(C_{src} + C_{dst}, 1))\)</p> 167 */ 168 PLUS, 169 170 /** 171 * {@usesMathJax} 172 * 173 * Multiplies the source and destination pixels. 174 * 175 * <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p> 176 * <p>\(C_{out} = C_{src} * C_{dst}\)</p> 177 * 178 */ 179 MODULATE, 180 181 /** 182 * {@usesMathJax} 183 * 184 * Adds the source and destination pixels, then subtracts the 185 * source pixels multiplied by the destination. 186 * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p> 187 * <p>\(C_{out} = C_{src} + C_{dst} - C_{src} * C_{dst}\)</p> 188 */ 189 SCREEN, 190 191 /** 192 * {@usesMathJax} 193 * 194 * Multiplies or screens the source and destination depending on the 195 * destination color. 196 * 197 * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p> 198 * <p>\(\begin{equation} 199 * C_{out} = \begin{cases} 2 * C_{src} * C_{dst} & 2 * C_{dst} \lt \alpha_{dst} \\ 200 * \alpha_{src} * \alpha_{dst} - 2 (\alpha_{dst} - C_{src}) (\alpha_{src} - C_{dst}) & 201 * otherwise \end{cases} 202 * \end{equation}\)</p> 203 */ 204 OVERLAY, 205 206 /** 207 * {@usesMathJax} 208 * 209 * Retains the smallest component of the source and 210 * destination pixels. 211 * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p> 212 * <p> 213 * \(C_{out} = 214 * (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst} + min(C_{src}, C_{dst})\) 215 * </p> 216 */ 217 DARKEN, 218 219 /** 220 * {@usesMathJax} 221 * 222 * Retains the largest component of the source and 223 * destination pixel. 224 * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p> 225 * <p> 226 * \(C_{out} = 227 * (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst} + max(C_{src}, C_{dst})\) 228 * </p> 229 */ 230 LIGHTEN, 231 232 /** 233 * {@usesMathJax} 234 * 235 * Makes destination brighter to reflect source. 236 * \(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\) 237 * </p> 238 * <p> 239 * \begin{equation} 240 * C_{out} = 241 * \begin{cases} 242 * C_{src} * (1 - \alpha_{dst}) & C_{dst} = 0 \\ 243 * C_{src} + \alpha_{dst}*(1 - \alpha_{src}) & C_{src} = \alpha_{src} \\ 244 * \alpha_{src} * min(\alpha_{dst}, C_{dst} * \alpha_{src}/(\alpha_{src} - C_{src})) 245 * + C_{src} *(1 - \alpha_{dst} + \alpha_{dst}*(1 - \alpha_{src}) & otherwise 246 * \end{cases} 247 * \end{equation} 248 * </p> 249 */ 250 @RequiresApi(Build.VERSION_CODES.Q) 251 COLOR_DODGE, 252 253 /** 254 * {@usesMathJax} 255 * 256 * Makes destination darker to reflect source. 257 * 258 * <p> 259 * \(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\) 260 * </p> 261 * <p> 262 * \begin{equation} 263 * C_{out} = 264 * \begin{cases} 265 * C_{dst} + C_{src}*(1 - \alpha_{dst}) & C_{dst} = \alpha_{dst} \\ 266 * \alpha_{dst}*(1 - \alpha_{src}) & C_{src} = 0 \\ 267 * \alpha_{src}*(\alpha_{dst} - min(\alpha_{dst}, (\alpha_{dst} 268 * - C_{dst})*\alpha_{src}/C_{src})) 269 * + C_{src} * (1 - \alpha_{dst}) + \alpha_{dst}*(1-\alpha_{src}) & otherwise 270 * \end{cases} 271 * \end{equation} 272 * </p> 273 */ 274 @RequiresApi(Build.VERSION_CODES.Q) 275 COLOR_BURN, 276 277 /** 278 * {@usesMathJax} 279 * 280 * Makes destination lighter or darker, depending on source. 281 * <p> 282 * \(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\) 283 * </p> 284 * <p> 285 * \begin{equation} 286 * C_{out} = 287 * \begin{cases} 288 * 2*C_{src}*C_{dst} & C_{src}*(1-\alpha_{dst}) + C_{dst}*(1-\alpha_{src}) + 2*C_{src} 289 * \leq \alpha_{src} \\ 290 * \alpha_{src}*\alpha_{dst}- 2*(\alpha_{dst} - C_{dst})*(\alpha_{src} - C_{src}) 291 * & otherwise 292 * \end{cases} 293 * \end{equation} 294 * </p> 295 */ 296 @RequiresApi(Build.VERSION_CODES.Q) 297 HARD_LIGHT, 298 299 /** 300 * {@usesMathJax} 301 * 302 * Makes destination lighter or darker, depending on source. 303 * <p> 304 * Where 305 * \begin{equation} 306 * m = 307 * \begin{cases} 308 * C_{dst} / \alpha_{dst} & \alpha_{dst} \gt 0 \\ 309 * 0 & otherwise 310 * \end{cases} 311 * \end{equation} 312 * </p> 313 * <p> 314 * \begin{equation} 315 * g = 316 * \begin{cases} 317 * (16 * m * m + 4 * m) * (m - 1) + 7 * m & 4 * C_{dst} \leq \alpha_{dst} \\ 318 * \sqrt m - m & otherwise 319 * \end{cases} 320 * \end{equation} 321 * </p> 322 * <p> 323 * \begin{equation} 324 * f = 325 * \begin{cases} 326 * C_{dst} * (\alpha_{src} + (2 * C_{src} - \alpha_{src}) * (1 - m)) 327 * & 2 * C_{src} \leq \alpha_{src} \\ 328 * C_{dst} * \alpha_{src} + \alpha_{dst} * (2 * C_{src} - \alpha_{src}) * g 329 * & otherwise 330 * \end{cases} 331 * \end{equation} 332 * </p> 333 * <p> 334 * \begin{equation} 335 * \alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst} 336 * \end{equation} 337 * \begin{equation} 338 * C_{out} = C_{src} / \alpha_{dst} + C_{dst} / \alpha_{src} + f 339 * \end{equation} 340 * </p> 341 */ 342 @RequiresApi(Build.VERSION_CODES.Q) 343 SOFT_LIGHT, 344 345 /** 346 * {@usesMathJax} 347 * 348 * Subtracts darker from lighter with higher contrast. 349 * <p> 350 * \begin{equation} 351 * \alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst} 352 * \end{equation} 353 * </p> 354 * <p> 355 * \begin{equation} 356 * C_{out} = C_{src} + C_{dst} - 2 * min(C_{src} 357 * * \alpha_{dst}, C_{dst} * \alpha_{src}) 358 * \end{equation} 359 * </p> 360 */ 361 @RequiresApi(Build.VERSION_CODES.Q) 362 DIFFERENCE, 363 364 /** 365 * {@usesMathJax} 366 * 367 * Subtracts darker from lighter with lower contrast. 368 * <p> 369 * \begin{equation} 370 * \alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst} 371 * \end{equation} 372 * </p> 373 * <p> 374 * \begin{equation} 375 * C_{out} = C_{src} + C_{dst} - 2 * C_{src} * C_{dst} 376 * \end{equation} 377 * </p> 378 */ 379 @RequiresApi(Build.VERSION_CODES.Q) 380 EXCLUSION, 381 382 /** 383 * {@usesMathJax} 384 * 385 * Multiplies the source and destination pixels. 386 * <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p> 387 * <p>\(C_{out} = 388 * C_{src} * (1 - \alpha_{dst}) + C_{dst} * (1 - \alpha_{src}) + (C_{src} * C_{dst})\) 389 * </p> 390 */ 391 @RequiresApi(Build.VERSION_CODES.Q) 392 MULTIPLY, 393 394 /** 395 * Replaces hue of destination with hue of source, leaving saturation 396 * and luminosity unchanged. 397 */ 398 @RequiresApi(Build.VERSION_CODES.Q) 399 HUE, 400 401 /** 402 * Replaces saturation of destination saturation hue of source, leaving hue and 403 * luminosity unchanged. 404 */ 405 @RequiresApi(Build.VERSION_CODES.Q) 406 SATURATION, 407 408 /** 409 * Replaces hue and saturation of destination with hue and saturation of source, 410 * leaving luminosity unchanged. 411 */ 412 @RequiresApi(Build.VERSION_CODES.Q) 413 COLOR, 414 415 /** 416 * Replaces luminosity of destination with luminosity of source, leaving hue and 417 * saturation unchanged. 418 */ 419 @RequiresApi(Build.VERSION_CODES.Q) 420 LUMINOSITY 421 } 422