Merge changes from topic 'bitmapfactory-options-outdecodecolorspace' into oc-dev

am: 81b292abdf

Change-Id: I75e541ec15651f63a47dac8f20e1955548f87f58
This commit is contained in:
Romain Guy
2017-04-01 04:22:17 +00:00
committed by android-build-merger
27 changed files with 481 additions and 51 deletions

View File

@@ -12510,6 +12510,7 @@ package android.graphics {
field public int inTargetDensity;
field public byte[] inTempStorage;
field public deprecated boolean mCancel;
field public android.graphics.ColorSpace outColorSpace;
field public android.graphics.Bitmap.Config outConfig;
field public int outHeight;
field public java.lang.String outMimeType;

View File

@@ -13240,6 +13240,7 @@ package android.graphics {
field public int inTargetDensity;
field public byte[] inTempStorage;
field public deprecated boolean mCancel;
field public android.graphics.ColorSpace outColorSpace;
field public android.graphics.Bitmap.Config outConfig;
field public int outHeight;
field public java.lang.String outMimeType;

View File

@@ -12560,6 +12560,7 @@ package android.graphics {
field public int inTargetDensity;
field public byte[] inTempStorage;
field public deprecated boolean mCancel;
field public android.graphics.ColorSpace outColorSpace;
field public android.graphics.Bitmap.Config outConfig;
field public int outHeight;
field public java.lang.String outMimeType;

View File

@@ -39,6 +39,7 @@ jfieldID gOptions_widthFieldID;
jfieldID gOptions_heightFieldID;
jfieldID gOptions_mimeFieldID;
jfieldID gOptions_outConfigFieldID;
jfieldID gOptions_outColorSpaceFieldID;
jfieldID gOptions_mCancelID;
jfieldID gOptions_bitmapFieldID;
@@ -50,6 +51,20 @@ jmethodID gInsetStruct_constructorMethodID;
jclass gBitmapConfig_class;
jmethodID gBitmapConfig_nativeToConfigMethodID;
jclass gColorSpace_class;
jmethodID gColorSpace_getMethodID;
jmethodID gColorSpace_matchMethodID;
jclass gColorSpaceRGB_class;
jmethodID gColorSpaceRGB_constructorMethodID;
jclass gColorSpace_Named_class;
jfieldID gColorSpace_Named_sRGBFieldID;
jfieldID gColorSpace_Named_LinearExtendedSRGBFieldID;
jclass gTransferParameters_class;
jmethodID gTransferParameters_constructorMethodID;
using namespace android;
jstring encodedFormatToString(JNIEnv* env, SkEncodedImageFormat format) {
@@ -228,6 +243,70 @@ static bool needsFineScale(const SkISize fullSize, const SkISize decodedSize,
needsFineScale(fullSize.height(), decodedSize.height(), sampleSize);
}
static jobject getColorSpace(JNIEnv* env,
sk_sp<SkColorSpace>& decodeColorSpace, SkColorType decodeColorType) {
jobject colorSpace = nullptr;
// No need to match, we know what the output color space will be
if (decodeColorType == kRGBA_F16_SkColorType) {
jobject linearExtendedSRGB = env->GetStaticObjectField(
gColorSpace_Named_class, gColorSpace_Named_LinearExtendedSRGBFieldID);
colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
gColorSpace_getMethodID, linearExtendedSRGB);
} else {
// Same here, no need to match
if (decodeColorSpace->isSRGB()) {
jobject sRGB = env->GetStaticObjectField(
gColorSpace_Named_class, gColorSpace_Named_sRGBFieldID);
colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
gColorSpace_getMethodID, sRGB);
} else if (decodeColorSpace.get() != nullptr) {
// Try to match against known RGB color spaces using the CIE XYZ D50
// conversion matrix and numerical transfer function parameters
SkMatrix44 xyzMatrix(SkMatrix44::kUninitialized_Constructor);
LOG_ALWAYS_FATAL_IF(!decodeColorSpace->toXYZD50(&xyzMatrix));
SkColorSpaceTransferFn transferParams;
// We can only handle numerical transfer functions at the moment
LOG_ALWAYS_FATAL_IF(!decodeColorSpace->isNumericalTransferFn(&transferParams));
jobject params = env->NewObject(gTransferParameters_class,
gTransferParameters_constructorMethodID,
transferParams.fA, transferParams.fB, transferParams.fC,
transferParams.fD, transferParams.fE, transferParams.fF,
transferParams.fG);
jfloatArray xyzArray = env->NewFloatArray(9);
jfloat xyz[9] = {
xyzMatrix.getFloat(0, 0),
xyzMatrix.getFloat(1, 0),
xyzMatrix.getFloat(2, 0),
xyzMatrix.getFloat(0, 1),
xyzMatrix.getFloat(1, 1),
xyzMatrix.getFloat(2, 1),
xyzMatrix.getFloat(0, 2),
xyzMatrix.getFloat(1, 2),
xyzMatrix.getFloat(2, 2)
};
env->SetFloatArrayRegion(xyzArray, 0, 9, xyz);
colorSpace = env->CallStaticObjectMethod(gColorSpace_class,
gColorSpace_matchMethodID, xyzArray, params);
if (colorSpace == nullptr) {
// We couldn't find an exact match, let's create a new color space
// instance with the 3x3 conversion matrix and transfer function
colorSpace = env->NewObject(gColorSpaceRGB_class,
gColorSpaceRGB_constructorMethodID,
env->NewStringUTF("Unknown"), xyzArray, params);
}
env->DeleteLocalRef(xyzArray);
}
}
return colorSpace;
}
static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding, jobject options) {
// This function takes ownership of the input stream. Since the SkAndroidCodec
// will take ownership of the stream, we don't necessarily need to take ownership
@@ -263,6 +342,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
env->SetIntField(options, gOptions_heightFieldID, -1);
env->SetObjectField(options, gOptions_mimeFieldID, 0);
env->SetObjectField(options, gOptions_outConfigFieldID, 0);
env->SetObjectField(options, gOptions_outColorSpaceFieldID, 0);
jobject jconfig = env->GetObjectField(options, gOptions_configFieldID);
prefColorType = GraphicsJNI::getNativeBitmapColorType(env, jconfig);
@@ -319,6 +399,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
// Set the decode colorType
SkColorType decodeColorType = codec->computeOutputColorType(prefColorType);
sk_sp<SkColorSpace> decodeColorSpace = codec->computeOutputColorSpace(decodeColorType);
// Set the options and return if the client only wants the size.
if (options != NULL) {
@@ -345,6 +426,9 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
gBitmapConfig_nativeToConfigMethodID, configID);
env->SetObjectField(options, gOptions_outConfigFieldID, config);
env->SetObjectField(options, gOptions_outColorSpaceFieldID,
getColorSpace(env, decodeColorSpace, decodeColorType));
if (onlyDecodeSize) {
return nullptr;
}
@@ -412,7 +496,7 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding
SkAlphaType alphaType = codec->computeOutputAlphaType(requireUnpremultiplied);
const SkImageInfo decodeInfo = SkImageInfo::Make(size.width(), size.height(),
decodeColorType, alphaType, codec->computeOutputColorSpace(decodeColorType));
decodeColorType, alphaType, decodeColorSpace);
// For wide gamut images, we will leave the color space on the SkBitmap. Otherwise,
// use the default.
@@ -725,6 +809,8 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) {
gOptions_mimeFieldID = GetFieldIDOrDie(env, options_class, "outMimeType", "Ljava/lang/String;");
gOptions_outConfigFieldID = GetFieldIDOrDie(env, options_class, "outConfig",
"Landroid/graphics/Bitmap$Config;");
gOptions_outColorSpaceFieldID = GetFieldIDOrDie(env, options_class, "outColorSpace",
"Landroid/graphics/ColorSpace;");
gOptions_mCancelID = GetFieldIDOrDie(env, options_class, "mCancel", "Z");
jclass bitmap_class = FindClassOrDie(env, "android/graphics/Bitmap");
@@ -741,6 +827,29 @@ int register_android_graphics_BitmapFactory(JNIEnv* env) {
gBitmapConfig_nativeToConfigMethodID = GetStaticMethodIDOrDie(env, gBitmapConfig_class,
"nativeToConfig", "(I)Landroid/graphics/Bitmap$Config;");
gColorSpace_class = MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/graphics/ColorSpace"));
gColorSpace_getMethodID = GetStaticMethodIDOrDie(env, gColorSpace_class,
"get", "(Landroid/graphics/ColorSpace$Named;)Landroid/graphics/ColorSpace;");
gColorSpace_matchMethodID = GetStaticMethodIDOrDie(env, gColorSpace_class, "match",
"([FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)Landroid/graphics/ColorSpace;");
gColorSpaceRGB_class = MakeGlobalRefOrDie(env,
FindClassOrDie(env, "android/graphics/ColorSpace$Rgb"));
gColorSpaceRGB_constructorMethodID = GetMethodIDOrDie(env, gColorSpaceRGB_class,
"<init>", "(Ljava/lang/String;[FLandroid/graphics/ColorSpace$Rgb$TransferParameters;)V");
gColorSpace_Named_class = MakeGlobalRefOrDie(env,
FindClassOrDie(env, "android/graphics/ColorSpace$Named"));
gColorSpace_Named_sRGBFieldID = GetStaticFieldIDOrDie(env,
gColorSpace_Named_class, "SRGB", "Landroid/graphics/ColorSpace$Named;");
gColorSpace_Named_LinearExtendedSRGBFieldID = GetStaticFieldIDOrDie(env,
gColorSpace_Named_class, "LINEAR_EXTENDED_SRGB", "Landroid/graphics/ColorSpace$Named;");
gTransferParameters_class = MakeGlobalRefOrDie(env, FindClassOrDie(env,
"android/graphics/ColorSpace$Rgb$TransferParameters"));
gTransferParameters_constructorMethodID = GetMethodIDOrDie(env, gTransferParameters_class,
"<init>", "(DDDDDDD)V");
return android::RegisterMethodsOrDie(env, "android/graphics/BitmapFactory",
gMethods, NELEM(gMethods));
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -360,6 +360,15 @@ public class BitmapFactory {
*/
public Bitmap.Config outConfig;
/**
* If known, the color space the decoded bitmap will have. Note that the
* output color space is not guaranteed to be the color space the bitmap
* is encoded with. If not known (when the config is
* {@link Bitmap.Config#ALPHA_8} for instance), or there is an error,
* it is set to null.
*/
public ColorSpace outColorSpace;
/**
* Temp storage to use for decoding. Suggest 16K or so.
*/

View File

@@ -143,7 +143,7 @@ import java.util.function.DoubleUnaryOperator;
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_renderer.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_renderer.png" />
* <figcaption style="text-align: center;">DCI-P3 vs ProPhoto RGB</figcaption>
* </p>
*
@@ -281,7 +281,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <figcaption style="text-align: center;">sRGB</figcaption>
* </p>
*/
@@ -308,7 +308,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <figcaption style="text-align: center;">sRGB</figcaption>
* </p>
*/
@@ -347,7 +347,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([-0.799..2.399[\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <figcaption style="text-align: center;">Extended sRGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -374,7 +374,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([-0.5..7.499[\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <figcaption style="text-align: center;">Extended sRGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -409,7 +409,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_bt709.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_bt709.png" />
* <figcaption style="text-align: center;">BT.709</figcaption>
* </p>
*/
@@ -444,7 +444,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_bt2020.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_bt2020.png" />
* <figcaption style="text-align: center;">BT.2020 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -471,7 +471,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_dci_p3.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_dci_p3.png" />
* <figcaption style="text-align: center;">DCI-P3 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -506,7 +506,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_display_p3.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_display_p3.png" />
* <figcaption style="text-align: center;">Display P3 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -541,7 +541,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_ntsc_1953.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_ntsc_1953.png" />
* <figcaption style="text-align: center;">NTSC 1953 (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -576,7 +576,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_smpte_c.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_smpte_c.png" />
* <figcaption style="text-align: center;">SMPTE-C (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -603,7 +603,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_adobe_rgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_adobe_rgb.png" />
* <figcaption style="text-align: center;">Adobe RGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -638,7 +638,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([0..1]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_pro_photo_rgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_pro_photo_rgb.png" />
* <figcaption style="text-align: center;">ProPhoto RGB (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -665,7 +665,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([-65504.0, 65504.0]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_aces.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_aces.png" />
* <figcaption style="text-align: center;">ACES (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -692,7 +692,7 @@ public abstract class ColorSpace {
* <tr><td>Range</td><td colspan="4">\([-65504.0, 65504.0]\)</td></tr>
* </table>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_acescg.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_acescg.png" />
* <figcaption style="text-align: center;">ACEScg (orange) vs sRGB (white)</figcaption>
* </p>
*/
@@ -1931,7 +1931,7 @@ public abstract class ColorSpace {
* are internally converted to xyY.</p>
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_srgb.png" />
* <figcaption style="text-align: center;">sRGB primaries and white point</figcaption>
* </p>
*
@@ -1989,7 +1989,7 @@ public abstract class ColorSpace {
* the range \([-65504, 65504]\).</p>
*
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_scrgb.png" />
* <figcaption style="text-align: center;">Extended sRGB and its large range</figcaption>
* </p>
*
@@ -3703,7 +3703,7 @@ public abstract class ColorSpace {
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
* <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
* </p>
*
@@ -3746,7 +3746,7 @@ public abstract class ColorSpace {
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
* <figcaption style="text-align: center;">Clipping disabled</figcaption>
* </p>
*
@@ -3759,7 +3759,7 @@ public abstract class ColorSpace {
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_clipped.png" />
* <figcaption style="text-align: center;">Clipping enabled</figcaption>
* </p>
*
@@ -3789,7 +3789,7 @@ public abstract class ColorSpace {
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_ucs.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_ucs.png" />
* <figcaption style="text-align: center;">CIE 1976 UCS diagram</figcaption>
* </p>
*
@@ -3847,7 +3847,7 @@ public abstract class ColorSpace {
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison.png" />
* <figcaption style="text-align: center;">sRGB vs DCI-P3</figcaption>
* </p>
*
@@ -3863,7 +3863,7 @@ public abstract class ColorSpace {
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_comparison2.png" />
* <figcaption style="text-align: center;">sRGB, DCI-P3, ACES and scRGB</figcaption>
* </p>
*
@@ -3901,7 +3901,7 @@ public abstract class ColorSpace {
* .render();
* </pre>
* <p>
* <img src="{@docRoot}reference/android/images/graphics/colorspace_points.png" />
* <img style="display: block; margin: 0 auto;" src="{@docRoot}reference/android/images/graphics/colorspace_points.png" />
* <figcaption style="text-align: center;">
* Locating colors on the chromaticity diagram
* </figcaption>

View File

@@ -1067,19 +1067,23 @@ public class Paint {
}
/**
* Get the paint's xfermode object.
* Get the paint's transfer mode object.
*
* @return the paint's xfermode (or null)
* @return the paint's transfer mode (or null)
*/
public Xfermode getXfermode() {
return mXfermode;
}
/**
* Set or clear the xfermode object.
* Set or clear the transfer mode object. A transfer mode defines how
* source pixels (generate by a drawing command) are composited with
* the destination pixels (content of the render target).
* <p />
* Pass null to clear any previous xfermode.
* Pass null to clear any previous transfer mode.
* As a convenience, the parameter passed is also returned.
* <p />
* {@link PorterDuffXfermode} is the most common transfer mode.
*
* @param xfermode May be null. The xfermode to be installed in the paint
* @return xfermode

View File

@@ -16,46 +16,345 @@
package android.graphics;
/**
* <p>This class contains the list of alpha compositing and blending modes
* that can be passed to {@link PorterDuffXfermode}, a specialized implementation
* of {@link Paint}'s {@link Paint#setXfermode(Xfermode) transfer mode}.
* All the available modes can be found in the {@link Mode} enum.</p>
*/
public class PorterDuff {
/**
* {@usesMathJax}
*
* <h3>Porter-Duff</h3>
*
* <p>The name of the parent class is an homage to the work of Thomas Porter and
* Tom Duff, presented in their seminal 1984 paper titled "Compositing Digital Images".
* In this paper, the authors describe 12 compositing operators that govern how to
* compute the color resulting of the composition of a source (the graphics object
* to render) with a destination (the content of the render target).</p>
*
* <p>"Compositing Digital Images" was published in <em>Computer Graphics</em>
* Volume 18, Number 3 dated July 1984.</p>
*
* <p>Because the work of Porter and Duff focuses solely on the effects of the alpha
* channel of the source and destination, the 12 operators described in the original
* paper are called alpha compositing modes here.</p>
*
* <p>For convenience, this class also provides several blending modes, which similarly
* define the result of compositing a source and a destination but without being
* constrained to the alpha channel. These blending modes are not defined by Porter
* and Duff but have been included in this class for convenience purposes.</p>
*
* <h3>Diagrams</h3>
*
* <p>All the example diagrams presented below use the same source and destination
* images:</p>
*
* <table summary="Source and Destination" style="background-color: transparent;">
* <tr>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_SRC.png" />
* <figcaption>Source image</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_DST.png" />
* <figcaption>Destination image</figcaption>
* </td>
* </tr>
* </table>
*
* <p>The order of drawing operations used to generate each diagram is shown in the
* following code snippet:</p>
*
* <pre class="prettyprint">
* Paint paint = new Paint();
* canvas.drawBitmap(destinationImage, 0, 0, paint);
*
* PorterDuff.Mode mode = // choose a mode
* paint.setXfermode(new PorterDuffXfermode(mode));
*
* canvas.drawBitmap(sourceImage, 0, 0, paint);
* </pre>
// these value must match their native equivalents. See SkXfermode.h
*
* <h3>Alpha compositing modes</h3>
*
* <table summary="Alpha compositing modes" style="background-color: transparent;">
* <tr>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_SRC.png" />
* <figcaption>{@link #SRC Source}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_SRC_OVER.png" />
* <figcaption>{@link #SRC_OVER Source Over}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_SRC_IN.png" />
* <figcaption>{@link #SRC_IN Source In}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_SRC_ATOP.png" />
* <figcaption>{@link #SRC_ATOP Source Atop}</figcaption>
* </td>
* </tr>
* <tr>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_DST.png" />
* <figcaption>{@link #DST Destination}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_DST_OVER.png" />
* <figcaption>{@link #DST_OVER Destination Over}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_DST_IN.png" />
* <figcaption>{@link #DST_IN Destination In}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_DST_ATOP.png" />
* <figcaption>{@link #DST_ATOP Destination Atop}</figcaption>
* </td>
* </tr>
* <tr>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_CLEAR.png" />
* <figcaption>{@link #CLEAR Clear}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_SRC_OUT.png" />
* <figcaption>{@link #SRC_OUT Source Out}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_DST_OUT.png" />
* <figcaption>{@link #DST_OUT Destination Out}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_XOR.png" />
* <figcaption>{@link #XOR Exclusive Or}</figcaption>
* </td>
* </tr>
* </table>
*
* <h3>Blending modes</h3>
*
* <table summary="Blending modes" style="background-color: transparent;">
* <tr>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_DARKEN.png" />
* <figcaption>{@link #DARKEN Darken}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_LIGHTEN.png" />
* <figcaption>{@link #LIGHTEN Lighten}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_MULTIPLY.png" />
* <figcaption>{@link #MULTIPLY Multiply}</figcaption>
* </td>
* </tr>
* <tr>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_SCREEN.png" />
* <figcaption>{@link #SCREEN Screen}</figcaption>
* </td>
* <td style="border: none; text-align: center;">
* <img src="{@docRoot}reference/android/images/graphics/composite_OVERLAY.png" />
* <figcaption>{@link #OVERLAY Overlay}</figcaption>
* </td>
* </tr>
* </table>
*
* <h3>Compositing equations</h3>
*
* <p>The documentation of each individual alpha compositing or blending mode below
* provides the exact equation used to compute alpha and color value of the result
* of the composition of a source and destination.</p>
*
* <p>The result (or output) alpha value is noted \(\alpha_{out}\). The result (or output)
* color value is noted \(C_{out}\).</p>
*/
public enum Mode {
/** [0, 0] */
// these value must match their native equivalents. See SkXfermode.h
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa, Sc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Da, Dc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa + (1 - Sa)*Da, Rc = Dc + (1 - Da)*Sc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa * Da, Sc * Da] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa * Da, Sa * Dc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa * (1 - Da), Sc * (1 - Da)] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Da * (1 - Sa), Dc * (1 - Sa)] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Da, Sc * Da + (1 - Sa) * Dc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa, Sa * Dc + Sc * (1 - Da)] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + min(Sc, Dc)] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa + Da - Sa*Da,
Sc*(1 - Da) + Dc*(1 - Sa) + max(Sc, Dc)] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** [Sa * Da, Sc * Dc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_MULTIPLY.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>
*/
MULTIPLY (13),
/** [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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),
/** Saturate(S + D) */
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_ADD.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>
*/
ADD (12),
/**
* <p>
* <img src="{@docRoot}reference/android/images/graphics/composite_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);
Mode(int nativeInt) {
@@ -71,14 +370,14 @@ public class PorterDuff {
/**
* @hide
*/
public static final int modeToInt(Mode mode) {
public static int modeToInt(Mode mode) {
return mode.nativeInt;
}
/**
* @hide
*/
public static final Mode intToMode(int val) {
public static Mode intToMode(int val) {
switch (val) {
default:
case 0: return Mode.CLEAR;

View File

@@ -16,6 +16,12 @@
package android.graphics;
/**
* <p>Specialized implementation of {@link Paint}'s
* {@link Paint#setXfermode(Xfermode) transfer mode}. Refer to the
* documentation of the {@link PorterDuff.Mode} enum for more
* information on the available alpha compositing and blending modes.</p>
*/
public class PorterDuffXfermode extends Xfermode {
/**
* Create an xfermode that uses the specified porter-duff mode.