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