Files
frameworks_base/graphics/java/android/graphics/BlendMode.java
Nader Jawad 52c090c749 Fix LaTeX formatting in Android documentation
Added missing usesMathJax tag within Javadoc for
each BlendMode enum value. This should ensure that the
blending formulas are rendered properly in the android documentation

Test: N/A
Bug: 130041190
Change-Id: I6c6dcc1804d8399468191bf758bf6cc7685918b5
(cherry picked from commit 39055b05e0)
2019-04-05 23:28:36 +00:00

589 lines
18 KiB
Java

/*
* Copyright (C) 2018 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.graphics;
import android.annotation.NonNull;
import android.annotation.Nullable;
public enum BlendMode {
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_CLEAR.png" />
* <figcaption>Destination pixels covered by the source are cleared to 0.</figcaption>
* </p>
* <p>\(\alpha_{out} = 0\)</p>
* <p>\(C_{out} = 0\)</p>
*/
CLEAR(0),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SRC.png" />
* <figcaption>The source pixels replace the destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src}\)</p>
* <p>\(C_{out} = C_{src}\)</p>
*/
SRC(1),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DST.png" />
* <figcaption>The source pixels are discarded, leaving the destination intact.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{dst}\)</p>
* <p>\(C_{out} = C_{dst}\)</p>
*/
DST(2),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SRC_OVER.png" />
* <figcaption>The source pixels are drawn over the destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} + (1 - \alpha_{src}) * \alpha_{dst}\)</p>
* <p>\(C_{out} = C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p>
*/
SRC_OVER(3),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DST_OVER.png" />
* <figcaption>The source pixels are drawn behind the destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{dst} + (1 - \alpha_{dst}) * \alpha_{src}\)</p>
* <p>\(C_{out} = C_{dst} + (1 - \alpha_{dst}) * C_{src}\)</p>
*/
DST_OVER(4),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SRC_IN.png" />
* <figcaption>Keeps the source pixels that cover the destination pixels,
* discards the remaining source and destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p>
* <p>\(C_{out} = C_{src} * \alpha_{dst}\)</p>
*/
SRC_IN(5),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DST_IN.png" />
* <figcaption>Keeps the destination pixels that cover source pixels,
* discards the remaining source and destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p>
* <p>\(C_{out} = C_{dst} * \alpha_{src}\)</p>
*/
DST_IN(6),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SRC_OUT.png" />
* <figcaption>Keeps the source pixels that do not cover destination pixels.
* Discards source pixels that cover destination pixels. Discards all
* destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = (1 - \alpha_{dst}) * \alpha_{src}\)</p>
* <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src}\)</p>
*/
SRC_OUT(7),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DST_OUT.png" />
* <figcaption>Keeps the destination pixels that are not covered by source pixels.
* Discards destination pixels that are covered by source pixels. Discards all
* source pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = (1 - \alpha_{src}) * \alpha_{dst}\)</p>
* <p>\(C_{out} = (1 - \alpha_{src}) * C_{dst}\)</p>
*/
DST_OUT(8),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SRC_ATOP.png" />
* <figcaption>Discards the source pixels that do not cover destination pixels.
* Draws remaining source pixels over destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{dst}\)</p>
* <p>\(C_{out} = \alpha_{dst} * C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p>
*/
SRC_ATOP(9),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DST_ATOP.png" />
* <figcaption>Discards the destination pixels that are not covered by source pixels.
* Draws remaining destination pixels over source pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src}\)</p>
* <p>\(C_{out} = \alpha_{src} * C_{dst} + (1 - \alpha_{dst}) * C_{src}\)</p>
*/
DST_ATOP(10),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_XOR.png" />
* <figcaption>Discards the source and destination pixels where source pixels
* cover destination pixels. Draws remaining source pixels.</figcaption>
* </p>
* <p>
* \(\alpha_{out} = (1 - \alpha_{dst}) * \alpha_{src} + (1 - \alpha_{src}) * \alpha_{dst}\)
* </p>
* <p>\(C_{out} = (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst}\)</p>
*/
XOR(11),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_PLUS.png" />
* <figcaption>Adds the source pixels to the destination pixels and saturates
* the result.</figcaption>
* </p>
* <p>\(\alpha_{out} = max(0, min(\alpha_{src} + \alpha_{dst}, 1))\)</p>
* <p>\(C_{out} = max(0, min(C_{src} + C_{dst}, 1))\)</p>
*/
PLUS(12),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_MODULATE.png" />
* <figcaption>Multiplies the source and destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} * \alpha_{dst}\)</p>
* <p>\(C_{out} = C_{src} * C_{dst}\)</p>
*
*/
MODULATE(13),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SCREEN.png" />
* <figcaption>
* Adds the source and destination pixels, then subtracts the
* source pixels multiplied by the destination.
* </figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
* <p>\(C_{out} = C_{src} + C_{dst} - C_{src} * C_{dst}\)</p>
*/
SCREEN(14),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_OVERLAY.png" />
* <figcaption>
* Multiplies or screens the source and destination depending on the
* destination color.
* </figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
* <p>\(\begin{equation}
* C_{out} = \begin{cases} 2 * C_{src} * C_{dst} & 2 * C_{dst} \lt \alpha_{dst} \\
* \alpha_{src} * \alpha_{dst} - 2 (\alpha_{dst} - C_{src}) (\alpha_{src} - C_{dst}) &
* otherwise \end{cases}
* \end{equation}\)</p>
*/
OVERLAY(15),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DARKEN.png" />
* <figcaption>
* Retains the smallest component of the source and
* destination pixels.
* </figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
* <p>
* \(C_{out} =
* (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst} + min(C_{src}, C_{dst})\)
* </p>
*/
DARKEN(16),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_LIGHTEN.png" />
* <figcaption>Retains the largest component of the source and
* destination pixel.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
* <p>
* \(C_{out} =
* (1 - \alpha_{dst}) * C_{src} + (1 - \alpha_{src}) * C_{dst} + max(C_{src}, C_{dst})\)
* </p>
*/
LIGHTEN(17),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_COLOR_DODGE.png" />
* <figcaption>Makes destination brighter to reflect source.</figcaption>
* </p>
* <p>
* \(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)
* </p>
* <p>
* \begin{equation}
* C_{out} =
* \begin{cases}
* C_{src} * (1 - \alpha_{dst}) & C_{dst} = 0 \\
* C_{src} + \alpha_{dst}*(1 - \alpha_{src}) & C_{src} = \alpha_{src} \\
* \alpha_{src} * min(\alpha_{dst}, C_{dst} * \alpha_{src}/(\alpha_{src} - C_{src}))
* + C_{src} *(1 - \alpha_{dst} + \alpha_{dst}*(1 - \alpha_{src}) & otherwise
* \end{cases}
* \end{equation}
* </p>
*/
COLOR_DODGE(18),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_COLOR_BURN.png" />
* <figcaption>Makes destination darker to reflect source.</figcaption>
* </p>
* <p>
* \(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)
* </p>
* <p>
* \begin{equation}
* C_{out} =
* \begin{cases}
* C_{dst} + C_{src}*(1 - \alpha_{dst}) & C_{dst} = \alpha_{dst} \\
* \alpha_{dst}*(1 - \alpha_{src}) & C_{src} = 0 \\
* \alpha_{src}*(\alpha_{dst} - min(\alpha_{dst}, (\alpha_{dst}
* - C_{dst})*\alpha_{src}/C_{src}))
* + C_{src} * (1 - \alpha_{dst}) + \alpha_{dst}*(1-\alpha_{src}) & otherwise
* \end{cases}
* \end{equation}
* </p>
*/
COLOR_BURN(19),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_HARD_LIGHT.png" />
* <figcaption>Makes destination lighter or darker, depending on source.</figcaption>
* </p>
* <p>
* \(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)
* </p>
* <p>
* \begin{equation}
* C_{out} =
* \begin{cases}
* 2*C_{src}*C_{dst} & C_{src}*(1-\alpha_{dst}) + C_{dst}*(1-\alpha_{src}) + 2*C_{src}
* \leq \alpha_{src} \\
* \alpha_{src}*\alpha_{dst}- 2*(\alpha_{dst} - C_{dst})*(\alpha_{src} - C_{src})
* & otherwise
* \end{cases}
* \end{equation}
* </p>
*/
HARD_LIGHT(20),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SOFT_LIGHT.png" />
* <figcaption>Makes destination lighter or darker, depending on source.</figcaption>
* </p>
* <p>
* Where
* \begin{equation}
* m =
* \begin{cases}
* C_{dst} / \alpha_{dst} & \alpha_{dst} \gt 0 \\
* 0 & otherwise
* \end{cases}
* \end{equation}
* </p>
* <p>
* \begin{equation}
* g =
* \begin{cases}
* (16 * m * m + 4 * m) * (m - 1) + 7 * m & 4 * C_{dst} \leq \alpha_{dst} \\
* \sqrt m - m & otherwise
* \end{cases}
* \end{equation}
* </p>
* <p>
* \begin{equation}
* f =
* \begin{cases}
* C_{dst} * (\alpha_{src} + (2 * C_{src} - \alpha_{src}) * (1 - m))
* & 2 * C_{src} \leq \alpha_{src} \\
* C_{dst} * \alpha_{src} + \alpha_{dst} * (2 * C_{src} - \alpha_{src}) * g
* & otherwise
* \end{cases}
* \end{equation}
* </p>
* <p>
* \begin{equation}
* \alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}
* \end{equation}
* \begin{equation}
* C_{out} = C_{src} / \alpha_{dst} + C_{dst} / \alpha_{src} + f
* \end{equation}
* </p>
*/
SOFT_LIGHT(21),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DIFFERENCE.png" />
* <figcaption>Subtracts darker from lighter with higher contrast.</figcaption>
* </p>
* <p>
* \begin{equation}
* \alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}
* \end{equation}
* </p>
* <p>
* \begin{equation}
* C_{out} = C_{src} + C_{dst} - 2 * min(C_{src}
* * \alpha_{dst}, C_{dst} * \alpha_{src})
* \end{equation}
* </p>
*/
DIFFERENCE(22),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_DIFFERENCE.png" />
* <figcaption>Subtracts darker from lighter with lower contrast.</figcaption>
* </p>
* <p>
* \begin{equation}
* \alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}
* \end{equation}
* </p>
* <p>
* \begin{equation}
* C_{out} = C_{src} + C_{dst} - 2 * C_{src} * C_{dst}
* \end{equation}
* </p>
*/
EXCLUSION(23),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_MODULATE.png" />
* <figcaption>Multiplies the source and destination pixels.</figcaption>
* </p>
* <p>\(\alpha_{out} = \alpha_{src} + \alpha_{dst} - \alpha_{src} * \alpha_{dst}\)</p>
* <p>\(C_{out} =
* C_{src} * (1 - \alpha_{dst}) + C_{dst} * (1 - \alpha_{src}) + (C_{src} * C_{dst})\)
* </p>
*/
MULTIPLY(24),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_HUE.png" />
* <figcaption>
* Replaces hue of destination with hue of source, leaving saturation
* and luminosity unchanged.
* </figcaption>
* </p>
*/
HUE(25),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_SATURATION.png" />
* <figcaption>
* Replaces saturation of destination saturation hue of source, leaving hue and
* luminosity unchanged.
* </figcaption>
* </p>
*/
SATURATION(26),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_COLOR.png" />
* <figcaption>
* Replaces hue and saturation of destination with hue and saturation of source,
* leaving luminosity unchanged.
* </figcaption>
* </p>
*/
COLOR(27),
/**
* {@usesMathJax}
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/blendmode_LUMINOSITY.png" />
* <figcaption>
* Replaces luminosity of destination with luminosity of source, leaving hue and
* saturation unchanged.
* </figcaption>
* </p>
*/
LUMINOSITY(28);
private static final BlendMode[] BLEND_MODES = values();
/**
* @hide
*/
public static @Nullable BlendMode fromValue(int value) {
for (BlendMode mode : BLEND_MODES) {
if (mode.mXfermode.porterDuffMode == value) {
return mode;
}
}
return null;
}
/**
* @hide
*/
public static int toValue(BlendMode mode) {
return mode.getXfermode().porterDuffMode;
}
/**
* @hide
*/
public static @Nullable PorterDuff.Mode blendModeToPorterDuffMode(@Nullable BlendMode mode) {
if (mode != null) {
switch (mode) {
case CLEAR:
return PorterDuff.Mode.CLEAR;
case SRC:
return PorterDuff.Mode.SRC;
case DST:
return PorterDuff.Mode.DST;
case SRC_OVER:
return PorterDuff.Mode.SRC_OVER;
case DST_OVER:
return PorterDuff.Mode.DST_OVER;
case SRC_IN:
return PorterDuff.Mode.SRC_IN;
case DST_IN:
return PorterDuff.Mode.DST_IN;
case SRC_OUT:
return PorterDuff.Mode.SRC_OUT;
case DST_OUT:
return PorterDuff.Mode.DST_OUT;
case SRC_ATOP:
return PorterDuff.Mode.SRC_ATOP;
case DST_ATOP:
return PorterDuff.Mode.DST_ATOP;
case XOR:
return PorterDuff.Mode.XOR;
case DARKEN:
return PorterDuff.Mode.DARKEN;
case LIGHTEN:
return PorterDuff.Mode.LIGHTEN;
// b/73224934 PorterDuff Multiply maps to Skia Modulate
case MODULATE:
return PorterDuff.Mode.MULTIPLY;
case SCREEN:
return PorterDuff.Mode.SCREEN;
case PLUS:
return PorterDuff.Mode.ADD;
case OVERLAY:
return PorterDuff.Mode.OVERLAY;
default:
return null;
}
} else {
return null;
}
}
@NonNull
private final Xfermode mXfermode;
BlendMode(int mode) {
mXfermode = new Xfermode();
mXfermode.porterDuffMode = mode;
}
/**
* @hide
*/
@NonNull
public Xfermode getXfermode() {
return mXfermode;
}
}