summaryrefslogtreecommitdiff
path: root/graphics/java
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/java')
-rw-r--r--graphics/java/android/graphics/BaseCanvas.java23
-rw-r--r--graphics/java/android/graphics/BaseRecordingCanvas.java23
-rw-r--r--graphics/java/android/graphics/Bitmap.java13
-rw-r--r--graphics/java/android/graphics/BitmapFactory.java37
-rw-r--r--graphics/java/android/graphics/BitmapRegionDecoder.java4
-rw-r--r--graphics/java/android/graphics/BitmapShader.java4
-rw-r--r--graphics/java/android/graphics/BlendMode.java58
-rw-r--r--graphics/java/android/graphics/Canvas.java28
-rw-r--r--graphics/java/android/graphics/ComposeShader.java22
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java12
-rw-r--r--graphics/java/android/graphics/NinePatch.java6
-rw-r--r--graphics/java/android/graphics/Paint.java18
-rw-r--r--graphics/java/android/graphics/PorterDuff.java3
-rw-r--r--graphics/java/android/graphics/PorterDuffXfermode.java5
-rw-r--r--graphics/java/android/graphics/RenderNode.java3
-rw-r--r--graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java6
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java6
-rw-r--r--graphics/java/android/graphics/drawable/BitmapDrawable.java39
-rw-r--r--graphics/java/android/graphics/drawable/ColorDrawable.java35
-rw-r--r--graphics/java/android/graphics/drawable/ColorStateListDrawable.java16
-rw-r--r--graphics/java/android/graphics/drawable/Drawable.java98
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java16
-rw-r--r--graphics/java/android/graphics/drawable/DrawableWrapper.java6
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java157
-rw-r--r--graphics/java/android/graphics/drawable/Icon.java35
-rw-r--r--graphics/java/android/graphics/drawable/LayerDrawable.java6
-rw-r--r--graphics/java/android/graphics/drawable/NinePatchDrawable.java34
-rw-r--r--graphics/java/android/graphics/drawable/ShapeDrawable.java35
-rw-r--r--graphics/java/android/graphics/drawable/VectorDrawable.java47
-rw-r--r--graphics/java/android/graphics/pdf/PdfRenderer.java7
-rw-r--r--graphics/java/android/graphics/text/MeasuredText.java2
31 files changed, 533 insertions, 271 deletions
diff --git a/graphics/java/android/graphics/BaseCanvas.java b/graphics/java/android/graphics/BaseCanvas.java
index fd3773588299..c9431e3178f0 100644
--- a/graphics/java/android/graphics/BaseCanvas.java
+++ b/graphics/java/android/graphics/BaseCanvas.java
@@ -112,14 +112,14 @@ public abstract class BaseCanvas {
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
throwIfCannotDraw(bitmap);
throwIfHasHwBitmapInSwMode(paint);
- nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
+ nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top,
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
bitmap.mDensity);
}
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
throwIfHasHwBitmapInSwMode(paint);
- nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
+ nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.getNativeInstance(), matrix.ni(),
paint != null ? paint.getNativeInstance() : 0);
}
@@ -144,7 +144,7 @@ public abstract class BaseCanvas {
bottom = src.bottom;
}
- nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+ nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
bitmap.mDensity);
}
@@ -170,7 +170,7 @@ public abstract class BaseCanvas {
bottom = src.bottom;
}
- nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+ nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
bitmap.mDensity);
}
@@ -229,7 +229,7 @@ public abstract class BaseCanvas {
// no mul by 2, since we need only 1 color per vertex
checkRange(colors.length, colorOffset, count);
}
- nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
+ nDrawBitmapMesh(mNativeCanvasWrapper, bitmap.getNativeInstance(), meshWidth, meshHeight,
verts, vertOffset, colors, colorOffset,
paint != null ? paint.getNativeInstance() : 0);
}
@@ -240,7 +240,7 @@ public abstract class BaseCanvas {
}
public void drawColor(@ColorInt int color) {
- nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+ nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode);
}
/**
@@ -664,10 +664,11 @@ public abstract class BaseCanvas {
}
}
- private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
- long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
+ private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle, float left,
+ float top, long nativePaintOrZero, int canvasDensity, int screenDensity,
+ int bitmapDensity);
- private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float srcLeft,
+ private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle, float srcLeft,
float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop, float dstRight,
float dstBottom, long nativePaintOrZero, int screenDensity, int bitmapDensity);
@@ -726,10 +727,10 @@ public abstract class BaseCanvas {
float dstLeft, float dstTop, float dstRight, float dstBottom, long nativePaintOrZero,
int screenDensity, int bitmapDensity);
- private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
+ private static native void nDrawBitmapMatrix(long nativeCanvas, long bitmapHandle,
long nativeMatrix, long nativePaint);
- private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
+ private static native void nDrawBitmapMesh(long nativeCanvas, long bitmapHandle, int meshWidth,
int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
long nativePaint);
diff --git a/graphics/java/android/graphics/BaseRecordingCanvas.java b/graphics/java/android/graphics/BaseRecordingCanvas.java
index 3e117411db01..028b784d24c2 100644
--- a/graphics/java/android/graphics/BaseRecordingCanvas.java
+++ b/graphics/java/android/graphics/BaseRecordingCanvas.java
@@ -67,7 +67,7 @@ public class BaseRecordingCanvas extends Canvas {
public final void drawBitmap(@NonNull Bitmap bitmap, float left, float top,
@Nullable Paint paint) {
throwIfCannotDraw(bitmap);
- nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top,
+ nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top,
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity,
bitmap.mDensity);
}
@@ -75,7 +75,7 @@ public class BaseRecordingCanvas extends Canvas {
@Override
public final void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix,
@Nullable Paint paint) {
- nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
+ nDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.getNativeInstance(), matrix.ni(),
paint != null ? paint.getNativeInstance() : 0);
}
@@ -100,7 +100,7 @@ public class BaseRecordingCanvas extends Canvas {
bottom = src.bottom;
}
- nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+ nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
bitmap.mDensity);
}
@@ -126,7 +126,7 @@ public class BaseRecordingCanvas extends Canvas {
bottom = src.bottom;
}
- nDrawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
+ nDrawBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance(), left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
bitmap.mDensity);
}
@@ -188,7 +188,7 @@ public class BaseRecordingCanvas extends Canvas {
// no mul by 2, since we need only 1 color per vertex
checkRange(colors.length, colorOffset, count);
}
- nDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
+ nDrawBitmapMesh(mNativeCanvasWrapper, bitmap.getNativeInstance(), meshWidth, meshHeight,
verts, vertOffset, colors, colorOffset,
paint != null ? paint.getNativeInstance() : 0);
}
@@ -200,7 +200,7 @@ public class BaseRecordingCanvas extends Canvas {
@Override
public final void drawColor(@ColorInt int color) {
- nDrawColor(mNativeCanvasWrapper, color, PorterDuff.Mode.SRC_OVER.nativeInt);
+ nDrawColor(mNativeCanvasWrapper, color, BlendMode.SRC_OVER.getXfermode().porterDuffMode);
}
/**
@@ -581,11 +581,12 @@ public class BaseRecordingCanvas extends Canvas {
}
@FastNative
- private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap, float left, float top,
- long nativePaintOrZero, int canvasDensity, int screenDensity, int bitmapDensity);
+ private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle, float left,
+ float top, long nativePaintOrZero, int canvasDensity, int screenDensity,
+ int bitmapDensity);
@FastNative
- private static native void nDrawBitmap(long nativeCanvas, Bitmap bitmap,
+ private static native void nDrawBitmap(long nativeCanvas, long bitmapHandle,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
long nativePaintOrZero, int screenDensity, int bitmapDensity);
@@ -663,11 +664,11 @@ public class BaseRecordingCanvas extends Canvas {
int screenDensity, int bitmapDensity);
@FastNative
- private static native void nDrawBitmapMatrix(long nativeCanvas, Bitmap bitmap,
+ private static native void nDrawBitmapMatrix(long nativeCanvas, long bitmapHandle,
long nativeMatrix, long nativePaint);
@FastNative
- private static native void nDrawBitmapMesh(long nativeCanvas, Bitmap bitmap, int meshWidth,
+ private static native void nDrawBitmapMesh(long nativeCanvas, long bitmapHandle, int meshWidth,
int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset,
long nativePaint);
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 4bd344f1964f..170dec26f361 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1813,21 +1813,22 @@ public final class Bitmap implements Parcelable {
}
/**
- * Fills the bitmap's pixels with the specified {@link Color}.
+ * Fills the bitmap's pixels with the specified {@code ColorLong}.
*
+ * @param color The color to fill as packed by the {@link Color} class.
* @throws IllegalStateException if the bitmap is not mutable.
- * @throws IllegalArgumentException if the color space encoded in the long
- * is invalid or unknown.
+ * @throws IllegalArgumentException if the color space encoded in the
+ * {@code ColorLong} is invalid or unknown.
*
*/
- public void eraseColor(@ColorLong long c) {
+ public void eraseColor(@ColorLong long color) {
checkRecycled("Can't erase a recycled bitmap");
if (!isMutable()) {
throw new IllegalStateException("cannot erase immutable bitmaps");
}
- ColorSpace cs = Color.colorSpace(c);
- nativeErase(mNativePtr, cs.getNativeInstance(), c);
+ ColorSpace cs = Color.colorSpace(color);
+ nativeErase(mNativePtr, cs.getNativeInstance(), color);
}
/**
diff --git a/graphics/java/android/graphics/BitmapFactory.java b/graphics/java/android/graphics/BitmapFactory.java
index 49c3a3ba68b8..5623a8a49b35 100644
--- a/graphics/java/android/graphics/BitmapFactory.java
+++ b/graphics/java/android/graphics/BitmapFactory.java
@@ -436,9 +436,15 @@ public class BitmapFactory {
static void validate(Options opts) {
if (opts == null) return;
- if (opts.inBitmap != null && opts.inBitmap.getConfig() == Bitmap.Config.HARDWARE) {
- throw new IllegalArgumentException(
- "Bitmaps with Config.HARDWARE are always immutable");
+ if (opts.inBitmap != null) {
+ if (opts.inBitmap.getConfig() == Bitmap.Config.HARDWARE) {
+ throw new IllegalArgumentException(
+ "Bitmaps with Config.HARDWARE are always immutable");
+ }
+ if (opts.inBitmap.isRecycled()) {
+ throw new IllegalArgumentException(
+ "Cannot reuse a recycled Bitmap");
+ }
}
if (opts.inMutable && opts.inPreferredConfig == Bitmap.Config.HARDWARE) {
@@ -459,6 +465,17 @@ public class BitmapFactory {
}
/**
+ * Helper for passing inBitmap's native pointer to native.
+ */
+ static long nativeInBitmap(Options opts) {
+ if (opts == null || opts.inBitmap == null) {
+ return 0;
+ }
+
+ return opts.inBitmap.getNativeInstance();
+ }
+
+ /**
* Helper for passing SkColorSpace pointer to native.
*
* @throws IllegalArgumentException if the ColorSpace is not Rgb or does
@@ -646,6 +663,7 @@ public class BitmapFactory {
Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "decodeBitmap");
try {
bm = nativeDecodeByteArray(data, offset, length, opts,
+ Options.nativeInBitmap(opts),
Options.nativeColorSpace(opts));
if (bm == null && opts != null && opts.inBitmap != null) {
@@ -741,7 +759,8 @@ public class BitmapFactory {
try {
if (is instanceof AssetManager.AssetInputStream) {
final long asset = ((AssetManager.AssetInputStream) is).getNativeAsset();
- bm = nativeDecodeAsset(asset, outPadding, opts, Options.nativeColorSpace(opts));
+ bm = nativeDecodeAsset(asset, outPadding, opts, Options.nativeInBitmap(opts),
+ Options.nativeColorSpace(opts));
} else {
bm = decodeStreamInternal(is, outPadding, opts);
}
@@ -769,6 +788,7 @@ public class BitmapFactory {
if (opts != null) tempStorage = opts.inTempStorage;
if (tempStorage == null) tempStorage = new byte[DECODE_BUFFER_SIZE];
return nativeDecodeStream(is, tempStorage, outPadding, opts,
+ Options.nativeInBitmap(opts),
Options.nativeColorSpace(opts));
}
@@ -813,6 +833,7 @@ public class BitmapFactory {
try {
if (nativeIsSeekable(fd)) {
bm = nativeDecodeFileDescriptor(fd, outPadding, opts,
+ Options.nativeInBitmap(opts),
Options.nativeColorSpace(opts));
} else {
FileInputStream fis = new FileInputStream(fd);
@@ -850,15 +871,15 @@ public class BitmapFactory {
@UnsupportedAppUsage
private static native Bitmap nativeDecodeStream(InputStream is, byte[] storage,
- Rect padding, Options opts, long colorSpaceHandle);
+ Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle);
@UnsupportedAppUsage
private static native Bitmap nativeDecodeFileDescriptor(FileDescriptor fd,
- Rect padding, Options opts, long colorSpaceHandle);
+ Rect padding, Options opts, long inBitmapHandle, long colorSpaceHandle);
@UnsupportedAppUsage
private static native Bitmap nativeDecodeAsset(long nativeAsset, Rect padding, Options opts,
- long colorSpaceHandle);
+ long inBitmapHandle, long colorSpaceHandle);
@UnsupportedAppUsage
private static native Bitmap nativeDecodeByteArray(byte[] data, int offset,
- int length, Options opts, long colorSpaceHandle);
+ int length, Options opts, long inBitmapHandle, long colorSpaceHandle);
private static native boolean nativeIsSeekable(FileDescriptor fd);
}
diff --git a/graphics/java/android/graphics/BitmapRegionDecoder.java b/graphics/java/android/graphics/BitmapRegionDecoder.java
index 1410423eafac..629d8c131b68 100644
--- a/graphics/java/android/graphics/BitmapRegionDecoder.java
+++ b/graphics/java/android/graphics/BitmapRegionDecoder.java
@@ -196,6 +196,7 @@ public final class BitmapRegionDecoder {
throw new IllegalArgumentException("rectangle is outside the image");
return nativeDecodeRegion(mNativeBitmapRegionDecoder, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top, options,
+ BitmapFactory.Options.nativeInBitmap(options),
BitmapFactory.Options.nativeColorSpace(options));
}
}
@@ -266,7 +267,8 @@ public final class BitmapRegionDecoder {
private static native Bitmap nativeDecodeRegion(long lbm,
int start_x, int start_y, int width, int height,
- BitmapFactory.Options options, long colorSpaceHandle);
+ BitmapFactory.Options options, long inBitmapHandle,
+ long colorSpaceHandle);
private static native int nativeGetWidth(long lbm);
private static native int nativeGetHeight(long lbm);
private static native void nativeClean(long lbm);
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index eb0f2e1e18f2..198d1e7bc956 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -62,9 +62,9 @@ public class BitmapShader extends Shader {
@Override
long createNativeInstance(long nativeMatrix) {
- return nativeCreate(nativeMatrix, mBitmap, mTileX, mTileY);
+ return nativeCreate(nativeMatrix, mBitmap.getNativeInstance(), mTileX, mTileY);
}
- private static native long nativeCreate(long nativeMatrix, Bitmap bitmap,
+ private static native long nativeCreate(long nativeMatrix, long bitmapHandle,
int shaderTileModeX, int shaderTileModeY);
}
diff --git a/graphics/java/android/graphics/BlendMode.java b/graphics/java/android/graphics/BlendMode.java
index 39392c89d170..0b267048d976 100644
--- a/graphics/java/android/graphics/BlendMode.java
+++ b/graphics/java/android/graphics/BlendMode.java
@@ -454,6 +454,64 @@ public enum BlendMode {
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;
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 7b3f3da111d5..6f00fc907849 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -95,7 +95,7 @@ public class Canvas extends BaseCanvas {
public Canvas() {
if (!isHardwareAccelerated()) {
// 0 means no native bitmap
- mNativeCanvasWrapper = nInitRaster(null);
+ mNativeCanvasWrapper = nInitRaster(0);
mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
this, mNativeCanvasWrapper);
} else {
@@ -117,7 +117,7 @@ public class Canvas extends BaseCanvas {
throw new IllegalStateException("Immutable bitmap passed to Canvas constructor");
}
throwIfCannotDraw(bitmap);
- mNativeCanvasWrapper = nInitRaster(bitmap);
+ mNativeCanvasWrapper = nInitRaster(bitmap.getNativeInstance());
mFinalizer = NoImagePreloadHolder.sRegistry.registerNativeAllocation(
this, mNativeCanvasWrapper);
mBitmap = bitmap;
@@ -185,7 +185,7 @@ public class Canvas extends BaseCanvas {
}
if (bitmap == null) {
- nSetBitmap(mNativeCanvasWrapper, null);
+ nSetBitmap(mNativeCanvasWrapper, 0);
mDensity = Bitmap.DENSITY_NONE;
} else {
if (!bitmap.isMutable()) {
@@ -193,7 +193,7 @@ public class Canvas extends BaseCanvas {
}
throwIfCannotDraw(bitmap);
- nSetBitmap(mNativeCanvasWrapper, bitmap);
+ nSetBitmap(mNativeCanvasWrapper, bitmap.getNativeInstance());
mDensity = bitmap.mDensity;
}
@@ -1364,14 +1364,16 @@ public class Canvas extends BaseCanvas {
private static native void nFreeCaches();
private static native void nFreeTextLayoutCaches();
- private static native long nInitRaster(Bitmap bitmap);
private static native long nGetNativeFinalizer();
private static native void nSetCompatibilityVersion(int apiLevel);
// ---------------- @FastNative -------------------
@FastNative
- private static native void nSetBitmap(long canvasHandle, Bitmap bitmap);
+ private static native long nInitRaster(long bitmapHandle);
+
+ @FastNative
+ private static native void nSetBitmap(long canvasHandle, long bitmapHandle);
@FastNative
private static native boolean nGetClipBounds(long nativeCanvas, Rect bounds);
@@ -1683,8 +1685,9 @@ public class Canvas extends BaseCanvas {
* Fill the entire canvas' bitmap (restricted to the current clip) with the specified color,
* using srcover porterduff mode.
*
- * @param color the color to draw onto the canvas
- * @throws IllegalArgumentException if the color space encoded in the long
+ * @param color the {@code ColorLong} to draw onto the canvas. See the {@link Color}
+ * class for details about {@code ColorLong}s.
+ * @throws IllegalArgumentException if the color space encoded in the {@code ColorLong}
* is invalid or unknown.
*/
public void drawColor(@ColorLong long color) {
@@ -1695,7 +1698,7 @@ public class Canvas extends BaseCanvas {
* Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
* porter-duff xfermode.
*
- * @param color the color to draw with
+ * @param color the color to draw onto the canvas
* @param mode the porter-duff mode to apply to the color
*
* @deprecated use {@link #drawColor(int, BlendMode)} instead
@@ -1709,7 +1712,7 @@ public class Canvas extends BaseCanvas {
* Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
* blendmode.
*
- * @param color the color to draw with
+ * @param color the color to draw onto the canvas
* @param mode the blendmode to apply to the color
*/
public void drawColor(@ColorInt int color, @NonNull BlendMode mode) {
@@ -1720,9 +1723,10 @@ public class Canvas extends BaseCanvas {
* Fill the entire canvas' bitmap (restricted to the current clip) with the specified color and
* blendmode.
*
- * @param color the color to draw with
+ * @param color the {@code ColorLong} to draw onto the canvas. See the {@link Color}
+ * class for details about {@code ColorLong}s.
* @param mode the blendmode to apply to the color
- * @throws IllegalArgumentException if the color space encoded in the long
+ * @throws IllegalArgumentException if the color space encoded in the {@code ColorLong}
* is invalid or unknown.
*/
public void drawColor(@ColorLong long color, @NonNull BlendMode mode) {
diff --git a/graphics/java/android/graphics/ComposeShader.java b/graphics/java/android/graphics/ComposeShader.java
index 189e1746e644..93ddb10d24bc 100644
--- a/graphics/java/android/graphics/ComposeShader.java
+++ b/graphics/java/android/graphics/ComposeShader.java
@@ -39,7 +39,10 @@ public class ComposeShader extends Shader {
* @param shaderB The colors from this shader are seen as the "src" by the mode
* @param mode The mode that combines the colors from the two shaders. If mode
* is null, then SRC_OVER is assumed.
+ *
+ * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead
*/
+ @Deprecated
public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB, @NonNull Xfermode mode) {
this(shaderA, shaderB, mode.porterDuffMode);
}
@@ -52,12 +55,29 @@ public class ComposeShader extends Shader {
* @param shaderA The colors from this shader are seen as the "dst" by the mode
* @param shaderB The colors from this shader are seen as the "src" by the mode
* @param mode The PorterDuff mode that combines the colors from the two shaders.
- */
+ *
+ * @deprecated use {@link #ComposeShader(Shader, Shader, BlendMode)} instead
+ */
+ @Deprecated
public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
@NonNull PorterDuff.Mode mode) {
this(shaderA, shaderB, mode.nativeInt);
}
+ /**
+ * Create a new compose shader, given shaders A, B, and a combining PorterDuff mode.
+ * When the mode is applied, it will be given the result from shader A as its
+ * "dst", and the result from shader B as its "src".
+ *
+ * @param shaderA The colors from this shader are seen as the "dst" by the mode
+ * @param shaderB The colors from this shader are seen as the "src" by the mode
+ * @param blendMode The blend mode that combines the colors from the two shaders.
+ */
+ public ComposeShader(@NonNull Shader shaderA, @NonNull Shader shaderB,
+ @NonNull BlendMode blendMode) {
+ this(shaderA, shaderB, blendMode.getXfermode().porterDuffMode);
+ }
+
private ComposeShader(Shader shaderA, Shader shaderB, int nativeMode) {
if (shaderA == null || shaderB == null) {
throw new IllegalArgumentException("Shader parameters must not be null");
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index bc744cc7af3d..b6b2d4e1c46a 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -682,8 +682,8 @@ public class HardwareRenderer {
/** @hide */
public boolean copyLayerInto(final TextureLayer layer, final Bitmap bitmap) {
- return nCopyLayerInto(mNativeProxy,
- layer.getDeferredLayerUpdater(), bitmap);
+ return nCopyLayerInto(mNativeProxy, layer.getDeferredLayerUpdater(),
+ bitmap.getNativeInstance());
}
/**
@@ -910,10 +910,10 @@ public class HardwareRenderer {
public static int copySurfaceInto(Surface surface, Rect srcRect, Bitmap bitmap) {
if (srcRect == null) {
// Empty rect means entire surface
- return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap);
+ return nCopySurfaceInto(surface, 0, 0, 0, 0, bitmap.getNativeInstance());
} else {
return nCopySurfaceInto(surface, srcRect.left, srcRect.top,
- srcRect.right, srcRect.bottom, bitmap);
+ srcRect.right, srcRect.bottom, bitmap.getNativeInstance());
}
}
@@ -1115,7 +1115,7 @@ public class HardwareRenderer {
private static native void nBuildLayer(long nativeProxy, long node);
- private static native boolean nCopyLayerInto(long nativeProxy, long layer, Bitmap bitmap);
+ private static native boolean nCopyLayerInto(long nativeProxy, long layer, long bitmapHandle);
private static native void nPushLayerUpdate(long nativeProxy, long layer);
@@ -1162,7 +1162,7 @@ public class HardwareRenderer {
private static native void nRemoveFrameMetricsObserver(long nativeProxy, long nativeObserver);
private static native int nCopySurfaceInto(Surface surface,
- int srcLeft, int srcTop, int srcRight, int srcBottom, Bitmap bitmap);
+ int srcLeft, int srcTop, int srcRight, int srcBottom, long bitmapHandle);
private static native Bitmap nCreateHardwareBitmap(long renderNode, int width, int height);
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 800247af4927..c4c1eaceb4fc 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -261,7 +261,8 @@ public class NinePatch {
* that are transparent.
*/
public final Region getTransparentRegion(Rect bounds) {
- long r = nativeGetTransparentRegion(mBitmap, mNativeChunk, bounds);
+ long r = nativeGetTransparentRegion(mBitmap.getNativeInstance(),
+ mNativeChunk, bounds);
return r != 0 ? new Region(r) : null;
}
@@ -282,5 +283,6 @@ public class NinePatch {
*/
private static native long validateNinePatchChunk(byte[] chunk);
private static native void nativeFinalize(long chunk);
- private static native long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location);
+ private static native long nativeGetTransparentRegion(long bitmapHandle, long chunk,
+ Rect location);
}
diff --git a/graphics/java/android/graphics/Paint.java b/graphics/java/android/graphics/Paint.java
index c48546103a6f..db5f06524c18 100644
--- a/graphics/java/android/graphics/Paint.java
+++ b/graphics/java/android/graphics/Paint.java
@@ -1029,9 +1029,8 @@ public class Paint {
* premultiplied, meaning that alpha can be any value, regardless of the
* values of r,g,b. See the {@link Color} class for more details.
*
- * @see Color for APIs that help manipulate a color long.
- *
- * @return the paint's color (and alpha).
+ * @return the paint's color, alpha, and {@code ColorSpace} encoded as a
+ * {@code ColorLong}
*/
@ColorLong
public long getColorLong() {
@@ -1052,7 +1051,7 @@ public class Paint {
}
/**
- * Set the paint's color with a {@link ColorLong}. Note that the color is
+ * Set the paint's color with a {@code ColorLong}. Note that the color is
* a long with an encoded {@link ColorSpace} as well as alpha and r,g,b.
* These values are not premultiplied, meaning that alpha can be any value,
* regardless of the values of r,g,b. See the {@link Color} class for more
@@ -1060,8 +1059,8 @@ public class Paint {
*
* @param color The new color (including alpha and {@link ColorSpace})
* to set in the paint.
- * @throws IllegalArgumentException if the color space encoded in the long
- * is invalid or unknown.
+ * @throws IllegalArgumentException if the color space encoded in the
+ * {@code ColorLong} is invalid or unknown.
*/
public void setColor(@ColorLong long color) {
ColorSpace cs = Color.colorSpace(color);
@@ -1491,8 +1490,8 @@ public class Paint {
* The alpha of the shadow will be the paint's alpha if the shadow color is
* opaque, or the alpha from the shadow color if not.
*
- * @throws IllegalArgumentException if the color space encoded in the long
- * is invalid or unknown.
+ * @throws IllegalArgumentException if the color space encoded in the
+ * {@code ColorLong} is invalid or unknown.
*/
public void setShadowLayer(float radius, float dx, float dy, @ColorLong long shadowColor) {
ColorSpace cs = Color.colorSpace(shadowColor);
@@ -1559,8 +1558,11 @@ public class Paint {
/**
* Returns the color of the shadow layer.
+ *
+ * @return the shadow layer's color encoded as a {@link ColorLong}.
* @see #setShadowLayer(float,float,float,int)
* @see #setShadowLayer(float,float,float,long)
+ * @see Color
*/
public @ColorLong long getShadowLayerColorLong() {
return mShadowLayerColor;
diff --git a/graphics/java/android/graphics/PorterDuff.java b/graphics/java/android/graphics/PorterDuff.java
index fba50430f2ef..459291b7565e 100644
--- a/graphics/java/android/graphics/PorterDuff.java
+++ b/graphics/java/android/graphics/PorterDuff.java
@@ -23,7 +23,10 @@ import android.annotation.UnsupportedAppUsage;
* 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>
+ *
+ * @deprecated Use {@link BlendMode} with {@link Paint#setBlendMode(BlendMode)} instead
*/
+@Deprecated
public class PorterDuff {
/**
* {@usesMathJax}
diff --git a/graphics/java/android/graphics/PorterDuffXfermode.java b/graphics/java/android/graphics/PorterDuffXfermode.java
index 84d953de91db..5b933c493162 100644
--- a/graphics/java/android/graphics/PorterDuffXfermode.java
+++ b/graphics/java/android/graphics/PorterDuffXfermode.java
@@ -21,6 +21,11 @@ package android.graphics;
* {@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>
+ *
+ * @deprecated Consider using {@link BlendMode} instead as it supports a wider
+ * set of blend modes than those defined in {@link PorterDuff.Mode}
+ *
+ * @see Paint#setBlendMode(BlendMode)
*/
public class PorterDuffXfermode extends Xfermode {
/**
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 9b4f2c1b51d5..ae7fe6c46f2f 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -284,9 +284,10 @@ public final class RenderNode {
private static final class CompositePositionUpdateListener implements PositionUpdateListener {
private final PositionUpdateListener[] mListeners;
+ private static final PositionUpdateListener[] sEmpty = new PositionUpdateListener[0];
CompositePositionUpdateListener(PositionUpdateListener... listeners) {
- mListeners = listeners;
+ mListeners = listeners != null ? listeners : sEmpty;
}
public CompositePositionUpdateListener with(PositionUpdateListener listener) {
diff --git a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
index cb12a7c6ba6b..7def322c1953 100644
--- a/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
+++ b/graphics/java/android/graphics/drawable/AdaptiveIconDrawable.java
@@ -27,6 +27,7 @@ import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -35,7 +36,6 @@ import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Shader;
@@ -701,13 +701,13 @@ public class AdaptiveIconDrawable extends Drawable implements Drawable.Callback
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.N_CHILDREN;
for (int i = 0; i < N; i++) {
final Drawable dr = array[i].mDrawable;
if (dr != null) {
- dr.setTintMode(tintMode);
+ dr.setTintMode(blendMode);
}
}
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
index d9dab98c2be1..f45bf9b783e8 100644
--- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java
@@ -33,12 +33,12 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.RecordingCanvas;
import android.graphics.Rect;
import android.graphics.RenderNode;
@@ -477,8 +477,8 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 {
}
@Override
- public void setTintMode(PorterDuff.Mode tintMode) {
- mAnimatedVectorState.mVectorDrawable.setTintMode(tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mAnimatedVectorState.mVectorDrawable.setTintMode(blendMode);
}
@Override
diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java
index 976190109e7c..6b30158a183a 100644
--- a/graphics/java/android/graphics/drawable/BitmapDrawable.java
+++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java
@@ -25,6 +25,8 @@ import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ImageDecoder;
@@ -33,9 +35,7 @@ import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Xfermode;
@@ -90,7 +90,7 @@ public class BitmapDrawable extends Drawable {
@UnsupportedAppUsage
private BitmapState mBitmapState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeFilter;
@UnsupportedAppUsage
private int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -527,8 +527,8 @@ public class BitmapDrawable extends Drawable {
}
final boolean clearColorFilter;
- if (mTintFilter != null && paint.getColorFilter() == null) {
- paint.setColorFilter(mTintFilter);
+ if (mBlendModeFilter != null && paint.getColorFilter() == null) {
+ paint.setColorFilter(mBlendModeFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
@@ -678,17 +678,19 @@ public class BitmapDrawable extends Drawable {
final BitmapState state = mBitmapState;
if (state.mTint != tint) {
state.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mBitmapState.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, tint,
+ mBitmapState.mBlendMode);
invalidateSelf();
}
}
@Override
- public void setTintMode(PorterDuff.Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final BitmapState state = mBitmapState;
- if (state.mTintMode != tintMode) {
- state.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, tintMode);
+ if (state.mBlendMode != blendMode) {
+ state.mBlendMode = blendMode;
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mBitmapState.mTint,
+ blendMode);
invalidateSelf();
}
}
@@ -706,7 +708,7 @@ public class BitmapDrawable extends Drawable {
*/
@UnsupportedAppUsage
public Mode getTintMode() {
- return mBitmapState.mTintMode;
+ return BlendMode.blendModeToPorterDuffMode(mBitmapState.mBlendMode);
}
/**
@@ -744,8 +746,9 @@ public class BitmapDrawable extends Drawable {
@Override
protected boolean onStateChange(int[] stateSet) {
final BitmapState state = mBitmapState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint,
+ state.mBlendMode);
return true;
}
return false;
@@ -864,7 +867,7 @@ public class BitmapDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.BitmapDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.BitmapDrawable_tint);
@@ -979,7 +982,8 @@ public class BitmapDrawable extends Drawable {
int[] mThemeAttrs = null;
Bitmap mBitmap = null;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
+
int mGravity = Gravity.FILL;
float mBaseAlpha = 1.0f;
Shader.TileMode mTileModeX = null;
@@ -1005,7 +1009,7 @@ public class BitmapDrawable extends Drawable {
BitmapState(BitmapState bitmapState) {
mBitmap = bitmapState.mBitmap;
mTint = bitmapState.mTint;
- mTintMode = bitmapState.mTintMode;
+ mBlendMode = bitmapState.mBlendMode;
mThemeAttrs = bitmapState.mThemeAttrs;
mChangingConfigurations = bitmapState.mChangingConfigurations;
mGravity = bitmapState.mGravity;
@@ -1065,7 +1069,8 @@ public class BitmapDrawable extends Drawable {
*/
private void updateLocalState(Resources res) {
mTargetDensity = resolveDensity(res, mBitmapState.mTargetDensity);
- mTintFilter = updateTintFilter(mTintFilter, mBitmapState.mTint, mBitmapState.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mBitmapState.mTint,
+ mBitmapState.mBlendMode);
computeBitmapSize();
}
}
diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java
index 3c449166d9d5..efa806afce70 100644
--- a/graphics/java/android/graphics/drawable/ColorDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorDrawable.java
@@ -26,13 +26,13 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Xfermode;
import android.util.AttributeSet;
import android.view.ViewDebug;
@@ -58,7 +58,7 @@ public class ColorDrawable extends Drawable {
@ViewDebug.ExportedProperty(deepExport = true, prefix = "state_")
private ColorState mColorState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeColorFilter;
private boolean mMutated;
@@ -111,9 +111,10 @@ public class ColorDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
final ColorFilter colorFilter = mPaint.getColorFilter();
- if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null || mTintFilter != null) {
+ if ((mColorState.mUseColor >>> 24) != 0 || colorFilter != null
+ || mBlendModeColorFilter != null) {
if (colorFilter == null) {
- mPaint.setColorFilter(mTintFilter);
+ mPaint.setColorFilter(mBlendModeColorFilter);
}
mPaint.setColor(mColorState.mUseColor);
@@ -208,22 +209,25 @@ public class ColorDrawable extends Drawable {
@Override
public void setTintList(ColorStateList tint) {
mColorState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mColorState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint,
+ mColorState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(Mode tintMode) {
- mColorState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mColorState.mBlendMode = blendMode;
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mColorState.mTint,
+ blendMode);
invalidateSelf();
}
@Override
protected boolean onStateChange(int[] stateSet) {
final ColorState state = mColorState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+ state.mBlendMode);
return true;
}
return false;
@@ -261,7 +265,7 @@ public class ColorDrawable extends Drawable {
@Override
public int getOpacity() {
- if (mTintFilter != null || mPaint.getColorFilter() != null) {
+ if (mBlendModeColorFilter != null || mPaint.getColorFilter() != null) {
return PixelFormat.TRANSLUCENT;
}
@@ -348,7 +352,7 @@ public class ColorDrawable extends Drawable {
int mUseColor; // basecolor modulated by setAlpha()
@Config int mChangingConfigurations;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
ColorState() {
// Empty constructor.
@@ -360,7 +364,7 @@ public class ColorDrawable extends Drawable {
mUseColor = state.mUseColor;
mChangingConfigurations = state.mChangingConfigurations;
mTint = state.mTint;
- mTintMode = state.mTintMode;
+ mBlendMode = state.mBlendMode;
}
@Override
@@ -398,6 +402,7 @@ public class ColorDrawable extends Drawable {
* after inflating or applying a theme.
*/
private void updateLocalState(Resources r) {
- mTintFilter = updateTintFilter(mTintFilter, mColorState.mTint, mColorState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mColorState.mTint,
+ mColorState.mBlendMode);
}
}
diff --git a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
index ee4d1e72c130..b94b11468371 100644
--- a/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/ColorStateListDrawable.java
@@ -21,10 +21,10 @@ import android.annotation.Nullable;
import android.content.pm.ActivityInfo;
import android.content.res.ColorStateList;
import android.content.res.Resources;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.util.MathUtils;
/**
@@ -114,9 +114,9 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
}
@Override
- public void setTintMode(@NonNull PorterDuff.Mode tintMode) {
- mState.mTintMode = tintMode;
- mColorDrawable.setTintMode(tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mState.mBlendMode = blendMode;
+ mColorDrawable.setTintMode(blendMode);
onStateChange(getState());
}
@@ -236,7 +236,7 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
ColorStateList mColor = null;
ColorStateList mTint = null;
int mAlpha = -1;
- PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
@ActivityInfo.Config int mChangingConfigurations = 0;
ColorStateListDrawableState() {
@@ -246,7 +246,7 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
mColor = state.mColor;
mTint = state.mTint;
mAlpha = state.mAlpha;
- mTintMode = state.mTintMode;
+ mBlendMode = state.mBlendMode;
mChangingConfigurations = state.mChangingConfigurations;
}
@@ -292,8 +292,8 @@ public class ColorStateListDrawable extends Drawable implements Drawable.Callbac
mColorDrawable.setTintList(mState.mTint);
}
- if (mState.mTintMode != DEFAULT_TINT_MODE) {
- mColorDrawable.setTintMode(mState.mTintMode);
+ if (mState.mBlendMode != DEFAULT_BLEND_MODE) {
+ mColorDrawable.setTintMode(mState.mBlendMode);
}
}
}
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 49d353057d59..adc04fb03e2a 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -30,6 +30,8 @@ import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -182,6 +184,7 @@ public abstract class Drawable {
private static final Rect ZERO_BOUNDS_RECT = new Rect();
static final PorterDuff.Mode DEFAULT_TINT_MODE = PorterDuff.Mode.SRC_IN;
+ static final BlendMode DEFAULT_BLEND_MODE = BlendMode.SRC_IN;
private int[] mStateSet = StateSet.WILD_CARD;
private int mLevel = 0;
@@ -210,6 +213,24 @@ public abstract class Drawable {
protected int mSrcDensityOverride = 0;
/**
+ * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and
+ * setTintMode(BlendMode) as each default implementation invokes the other in order to
+ * support new use cases that utilize the new blending modes as well as support the legacy
+ * use cases. This flag tracks that {@link #setTintMode(BlendMode)} is only invoked once
+ * per invocation.
+ */
+ private boolean mSetBlendModeInvoked = false;
+
+ /**
+ * Flag used to break the recursive loop between setTintMode(PorterDuff.Mode) and
+ * setTintMode(BlendMode) as each default implementation invokes the other in order to
+ * support new use cases that utilize the new blending modes as well as support the legacy
+ * use cases. This flag tracks that {@link #setTintMode(Mode)} is only invoked once
+ * per invocation;
+ */
+ private boolean mSetTintModeInvoked = false;
+
+ /**
* Draw in its bounds (set via setBounds) respecting optional effects such
* as alpha (set via setAlpha) and color filter (set via setColorFilter).
*
@@ -630,6 +651,7 @@ public abstract class Drawable {
* @param tintColor Color to use for tinting this drawable
* @see #setTintList(ColorStateList)
* @see #setTintMode(PorterDuff.Mode)
+ * @see #setTintMode(BlendMode)
*/
public void setTint(@ColorInt int tintColor) {
setTintList(ColorStateList.valueOf(tintColor));
@@ -651,6 +673,7 @@ public abstract class Drawable {
* {@code null} to clear the tint
* @see #setTint(int)
* @see #setTintMode(PorterDuff.Mode)
+ * @see #setTintMode(BlendMode)
*/
public void setTintList(@Nullable ColorStateList tint) {}
@@ -665,11 +688,47 @@ public abstract class Drawable {
* {@link #setColorFilter(int, PorterDuff.Mode)} overrides tint.
* </p>
*
- * @param tintMode A Porter-Duff blending mode
+ * @param tintMode A Porter-Duff blending mode to apply to the drawable, a value of null sets
+ * the default Porter-Diff blending mode value
+ * of {@link PorterDuff.Mode#SRC_IN}
+ * @see #setTint(int)
+ * @see #setTintList(ColorStateList)
+ *
+ * @deprecated use {@link #setTintMode(BlendMode)} instead
+ */
+ @Deprecated
+ public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
+ if (!mSetTintModeInvoked) {
+ mSetTintModeInvoked = true;
+ BlendMode mode = tintMode != null ? BlendMode.fromValue(tintMode.nativeInt) : null;
+ setTintMode(mode != null ? mode : Drawable.DEFAULT_BLEND_MODE);
+ mSetTintModeInvoked = false;
+ }
+ }
+
+ /**
+ * Specifies a tint blending mode for this drawable.
+ * <p>
+ * Defines how this drawable's tint color should be blended into the drawable
+ * before it is drawn to screen. Default tint mode is {@link BlendMode#SRC_IN}.
+ * </p>
+ * <p class="note"><strong>Note:</strong> Setting a color filter via
+ * {@link #setColorFilter(ColorFilter)}
+ * </p>
+ *
+ * @param blendMode BlendMode to apply to the drawable, a value of null sets the default
+ * blend mode value of {@link BlendMode#SRC_IN}
* @see #setTint(int)
* @see #setTintList(ColorStateList)
*/
- public void setTintMode(@NonNull PorterDuff.Mode tintMode) {}
+ public void setTintMode(@Nullable BlendMode blendMode) {
+ if (!mSetBlendModeInvoked) {
+ mSetBlendModeInvoked = true;
+ PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode);
+ setTintMode(mode != null ? mode : Drawable.DEFAULT_TINT_MODE);
+ mSetBlendModeInvoked = false;
+ }
+ }
/**
* Returns the current color filter, or {@code null} if none set.
@@ -1540,6 +1599,20 @@ public abstract class Drawable {
return tintFilter;
}
+ @Nullable BlendModeColorFilter updateBlendModeFilter(@Nullable BlendModeColorFilter blendFilter,
+ @Nullable ColorStateList tint, @Nullable BlendMode blendMode) {
+ if (tint == null || blendMode == null) {
+ return null;
+ }
+
+ final int color = tint.getColorForState(getState(), Color.TRANSPARENT);
+ if (blendFilter == null || blendFilter.getColor() != color
+ || blendFilter.getMode() != blendMode) {
+ return new BlendModeColorFilter(color, blendMode);
+ }
+ return blendFilter;
+ }
+
/**
* Obtains styled attributes from the theme, if available, or unstyled
* resources if the theme is null.
@@ -1642,5 +1715,26 @@ public abstract class Drawable {
default: return defaultMode;
}
}
+
+ /**
+ * Parses a {@link android.graphics.BlendMode} from a tintMode
+ * attribute's enum value.
+ *
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public static BlendMode parseBlendMode(int value, BlendMode defaultMode) {
+ switch (value) {
+ case 3: return BlendMode.SRC_OVER;
+ case 5: return BlendMode.SRC_IN;
+ case 9: return BlendMode.SRC_ATOP;
+ // b/73224934 PorterDuff Multiply maps to Skia Modulate so actually
+ // return BlendMode.MODULATE here
+ case 14: return BlendMode.MODULATE;
+ case 15: return BlendMode.SCREEN;
+ case 16: return BlendMode.PLUS;
+ default: return defaultMode;
+ }
+ }
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 77e77c49973c..3e0881aef9ed 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -22,12 +22,12 @@ import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.os.Build;
import android.os.SystemClock;
@@ -196,14 +196,14 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
mDrawableContainerState.mHasTintMode = true;
- if (mDrawableContainerState.mTintMode != tintMode) {
- mDrawableContainerState.mTintMode = tintMode;
+ if (mDrawableContainerState.mBlendMode != blendMode) {
+ mDrawableContainerState.mBlendMode = blendMode;
if (mCurrDrawable != null) {
- mCurrDrawable.setTintMode(tintMode);
+ mCurrDrawable.setTintMode(blendMode);
}
}
}
@@ -544,7 +544,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
d.setTintList(mDrawableContainerState.mTintList);
}
if (mDrawableContainerState.mHasTintMode) {
- d.setTintMode(mDrawableContainerState.mTintMode);
+ d.setTintMode(mDrawableContainerState.mBlendMode);
}
}
@@ -730,7 +730,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
boolean mHasColorFilter;
ColorStateList mTintList;
- Mode mTintMode;
+ BlendMode mBlendMode;
boolean mHasTintList;
boolean mHasTintMode;
@@ -762,7 +762,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
mColorFilter = orig.mColorFilter;
mHasColorFilter = orig.mHasColorFilter;
mTintList = orig.mTintList;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
mHasTintList = orig.mHasTintList;
mHasTintMode = orig.mHasTintMode;
diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java
index 70c90eb05b17..d81401d451ca 100644
--- a/graphics/java/android/graphics/drawable/DrawableWrapper.java
+++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java
@@ -24,12 +24,12 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Xfermode;
import android.util.AttributeSet;
@@ -324,9 +324,9 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb
}
@Override
- public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
if (mDrawable != null) {
- mDrawable.setTintMode(tintMode);
+ mDrawable.setTintMode(blendMode);
}
}
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index e58e80225292..6948bc4fd61b 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -28,6 +28,8 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -38,8 +40,6 @@ import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
@@ -169,7 +169,7 @@ public class GradientDrawable extends Drawable {
@UnsupportedAppUsage
private Paint mStrokePaint; // optional, set by the caller
private ColorFilter mColorFilter; // optional, set by the caller
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeColorFilter;
private int mAlpha = 0xFF; // modified by the caller
private final Path mPath = new Path();
@@ -731,7 +731,7 @@ public class GradientDrawable extends Drawable {
mStrokePaint.getStrokeWidth() > 0;
final boolean haveFill = currFillAlpha > 0;
final GradientState st = mGradientState;
- final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mTintFilter;
+ final ColorFilter colorFilter = mColorFilter != null ? mColorFilter : mBlendModeColorFilter;
/* we need a layer iff we're drawing both a fill and stroke, and the
stroke is non-opaque, and our shapetype actually supports
@@ -1130,8 +1130,9 @@ public class GradientDrawable extends Drawable {
}
}
- if (s.mTint != null && s.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, s.mTint, s.mTintMode);
+ if (s.mTint != null && s.mBlendMode != null) {
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, s.mTint,
+ s.mBlendMode);
invalidateSelf = true;
}
@@ -1204,14 +1205,16 @@ public class GradientDrawable extends Drawable {
@Override
public void setTintList(@Nullable ColorStateList tint) {
mGradientState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode);
+ mBlendModeColorFilter =
+ updateBlendModeFilter(mBlendModeColorFilter, tint, mGradientState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
- mGradientState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mGradientState.mBlendMode = blendMode;
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mGradientState.mTint,
+ blendMode);
invalidateSelf();
}
@@ -1309,6 +1312,10 @@ public class GradientDrawable extends Drawable {
y0 = r.top + (r.bottom - r.top) * st.mCenterY;
float radius = st.mGradientRadius;
+ if (Float.compare(radius, 0.0f) == -1 || Float.isNaN(radius)) {
+ throw new IllegalArgumentException("Gradient radius must be a valid "
+ + "number greater than or equal to 0");
+ }
if (st.mGradientRadiusType == RADIUS_TYPE_FRACTION) {
// Fall back to parent width or height if intrinsic
// size is not specified.
@@ -1465,7 +1472,7 @@ public class GradientDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.GradientDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, PorterDuff.Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.GradientDrawable_tint);
@@ -1756,75 +1763,68 @@ public class GradientDrawable extends Drawable {
st.mGradientColors[1] = endColor;
}
- if (st.mGradient == LINEAR_GRADIENT) {
- int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
- angle %= 360;
+ int angle = (int) a.getFloat(R.styleable.GradientDrawableGradient_angle, st.mAngle);
+ angle %= 360;
- if (angle % 45 != 0) {
- throw new XmlPullParserException(a.getPositionDescription()
- + "<gradient> tag requires 'angle' attribute to "
- + "be a multiple of 45");
- }
+ if (angle % 45 != 0) {
+ throw new XmlPullParserException(a.getPositionDescription()
+ + "<gradient> tag requires 'angle' attribute to "
+ + "be a multiple of 45");
+ }
- st.mAngle = angle;
-
- switch (angle) {
- case 0:
- st.mOrientation = Orientation.LEFT_RIGHT;
- break;
- case 45:
- st.mOrientation = Orientation.BL_TR;
- break;
- case 90:
- st.mOrientation = Orientation.BOTTOM_TOP;
- break;
- case 135:
- st.mOrientation = Orientation.BR_TL;
- break;
- case 180:
- st.mOrientation = Orientation.RIGHT_LEFT;
- break;
- case 225:
- st.mOrientation = Orientation.TR_BL;
- break;
- case 270:
- st.mOrientation = Orientation.TOP_BOTTOM;
- break;
- case 315:
- st.mOrientation = Orientation.TL_BR;
- break;
- }
- } else {
- final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
- if (tv != null) {
- final float radius;
- final @RadiusType int radiusType;
- if (tv.type == TypedValue.TYPE_FRACTION) {
- radius = tv.getFraction(1.0f, 1.0f);
-
- final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
- & TypedValue.COMPLEX_UNIT_MASK;
- if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
- radiusType = RADIUS_TYPE_FRACTION_PARENT;
- } else {
- radiusType = RADIUS_TYPE_FRACTION;
- }
- } else if (tv.type == TypedValue.TYPE_DIMENSION) {
- radius = tv.getDimension(r.getDisplayMetrics());
- radiusType = RADIUS_TYPE_PIXELS;
+ st.mAngle = angle;
+
+ switch (angle) {
+ case 0:
+ st.mOrientation = Orientation.LEFT_RIGHT;
+ break;
+ case 45:
+ st.mOrientation = Orientation.BL_TR;
+ break;
+ case 90:
+ st.mOrientation = Orientation.BOTTOM_TOP;
+ break;
+ case 135:
+ st.mOrientation = Orientation.BR_TL;
+ break;
+ case 180:
+ st.mOrientation = Orientation.RIGHT_LEFT;
+ break;
+ case 225:
+ st.mOrientation = Orientation.TR_BL;
+ break;
+ case 270:
+ st.mOrientation = Orientation.TOP_BOTTOM;
+ break;
+ case 315:
+ st.mOrientation = Orientation.TL_BR;
+ break;
+ }
+
+ final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius);
+ if (tv != null) {
+ final float radius;
+ final @RadiusType int radiusType;
+ if (tv.type == TypedValue.TYPE_FRACTION) {
+ radius = tv.getFraction(1.0f, 1.0f);
+
+ final int unit = (tv.data >> TypedValue.COMPLEX_UNIT_SHIFT)
+ & TypedValue.COMPLEX_UNIT_MASK;
+ if (unit == TypedValue.COMPLEX_UNIT_FRACTION_PARENT) {
+ radiusType = RADIUS_TYPE_FRACTION_PARENT;
} else {
- radius = tv.getFloat();
- radiusType = RADIUS_TYPE_PIXELS;
+ radiusType = RADIUS_TYPE_FRACTION;
}
-
- st.mGradientRadius = radius;
- st.mGradientRadiusType = radiusType;
- } else if (st.mGradient == RADIAL_GRADIENT) {
- throw new XmlPullParserException(
- a.getPositionDescription()
- + "<gradient> tag requires 'gradientRadius' "
- + "attribute with radial type");
+ } else if (tv.type == TypedValue.TYPE_DIMENSION) {
+ radius = tv.getDimension(r.getDisplayMetrics());
+ radiusType = RADIUS_TYPE_PIXELS;
+ } else {
+ radius = tv.getFloat();
+ radiusType = RADIUS_TYPE_PIXELS;
}
+
+ st.mGradientRadius = radius;
+ st.mGradientRadiusType = radiusType;
}
}
@@ -2010,7 +2010,7 @@ public class GradientDrawable extends Drawable {
boolean mOpaqueOverShape;
ColorStateList mTint = null;
- PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
int mDensity = DisplayMetrics.DENSITY_DEFAULT;
@@ -2068,7 +2068,7 @@ public class GradientDrawable extends Drawable {
mOpaqueOverBounds = orig.mOpaqueOverBounds;
mOpaqueOverShape = orig.mOpaqueOverShape;
mTint = orig.mTint;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
mThemeAttrs = orig.mThemeAttrs;
mAttrSize = orig.mAttrSize;
mAttrGradient = orig.mAttrGradient;
@@ -2355,7 +2355,8 @@ public class GradientDrawable extends Drawable {
}
}
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+ state.mBlendMode);
mGradientIsDirty = true;
state.computeOpacity();
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 71dd7a2f4800..5fd18a1431e0 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -30,6 +30,7 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.BlendMode;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.AsyncTask;
@@ -105,8 +106,8 @@ public final class Icon implements Parcelable {
private final int mType;
private ColorStateList mTintList;
- static final PorterDuff.Mode DEFAULT_TINT_MODE = Drawable.DEFAULT_TINT_MODE; // SRC_IN
- private PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE;
+ static final BlendMode DEFAULT_BLEND_MODE = Drawable.DEFAULT_BLEND_MODE; // SRC_IN
+ private BlendMode mBlendMode = Drawable.DEFAULT_BLEND_MODE;
// To avoid adding unnecessary overhead, we have a few basic objects that get repurposed
// based on the value of mType.
@@ -320,10 +321,10 @@ public final class Icon implements Parcelable {
*/
public Drawable loadDrawable(Context context) {
final Drawable result = loadDrawableInner(context);
- if (result != null && (mTintList != null || mTintMode != DEFAULT_TINT_MODE)) {
+ if (result != null && (mTintList != null || mBlendMode != DEFAULT_BLEND_MODE)) {
result.mutate();
result.setTintList(mTintList);
- result.setTintMode(mTintMode);
+ result.setTintMode(mBlendMode);
}
return result;
}
@@ -695,16 +696,30 @@ public final class Icon implements Parcelable {
*
* @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null
* @return this same object, for use in chained construction
+ *
+ * @deprecated use {@link #setTintMode(BlendMode)} instead
+ */
+ @Deprecated
+ public @NonNull Icon setTintMode(@NonNull PorterDuff.Mode mode) {
+ mBlendMode = BlendMode.fromValue(mode.nativeInt);
+ return this;
+ }
+
+ /**
+ * Store a blending mode to use whenever this Icon is drawn.
+ *
+ * @param mode a blending mode, as in {@link Drawable#setTintMode(PorterDuff.Mode)}, may be null
+ * @return this same object, for use in chained construction
*/
- public Icon setTintMode(PorterDuff.Mode mode) {
- mTintMode = mode;
+ public @NonNull Icon setTintMode(@NonNull BlendMode mode) {
+ mBlendMode = mode;
return this;
}
/** @hide */
@UnsupportedAppUsage
public boolean hasTint() {
- return (mTintList != null) || (mTintMode != DEFAULT_TINT_MODE);
+ return (mTintList != null) || (mBlendMode != DEFAULT_BLEND_MODE);
}
/**
@@ -757,7 +772,7 @@ public final class Icon implements Parcelable {
sep = "|";
}
}
- if (mTintMode != DEFAULT_TINT_MODE) sb.append(" mode=").append(mTintMode);
+ if (mBlendMode != DEFAULT_BLEND_MODE) sb.append(" mode=").append(mBlendMode);
sb.append(")");
return sb.toString();
}
@@ -807,7 +822,7 @@ public final class Icon implements Parcelable {
if (in.readInt() == 1) {
mTintList = ColorStateList.CREATOR.createFromParcel(in);
}
- mTintMode = PorterDuff.intToMode(in.readInt());
+ mBlendMode = BlendMode.fromValue(in.readInt());
}
@Override
@@ -837,7 +852,7 @@ public final class Icon implements Parcelable {
dest.writeInt(1);
mTintList.writeToParcel(dest, flags);
}
- dest.writeInt(PorterDuff.modeToInt(mTintMode));
+ dest.writeInt(BlendMode.toValue(mBlendMode));
}
public static final @android.annotation.NonNull Parcelable.Creator<Icon> CREATOR
diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java
index b4392c8d023f..e2c84927b578 100644
--- a/graphics/java/android/graphics/drawable/LayerDrawable.java
+++ b/graphics/java/android/graphics/drawable/LayerDrawable.java
@@ -24,11 +24,11 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -1397,13 +1397,13 @@ public class LayerDrawable extends Drawable implements Drawable.Callback {
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final ChildDrawable[] array = mLayerState.mChildren;
final int N = mLayerState.mNumChildren;
for (int i = 0; i < N; i++) {
final Drawable dr = array[i].mDrawable;
if (dr != null) {
- dr.setTintMode(tintMode);
+ dr.setTintMode(blendMode);
}
}
}
diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
index b53477137331..4972e6a82b7d 100644
--- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java
+++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java
@@ -25,6 +25,8 @@ import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.ImageDecoder;
@@ -33,9 +35,6 @@ import android.graphics.NinePatch;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Region;
import android.util.AttributeSet;
@@ -73,7 +72,7 @@ public class NinePatchDrawable extends Drawable {
@UnsupportedAppUsage
private NinePatchState mNinePatchState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeFilter;
private Rect mPadding;
private Insets mOpticalInsets = Insets.NONE;
private Rect mOutlineInsets;
@@ -198,8 +197,8 @@ public class NinePatchDrawable extends Drawable {
int restoreToCount = -1;
final boolean clearColorFilter;
- if (mTintFilter != null && getPaint().getColorFilter() == null) {
- mPaint.setColorFilter(mTintFilter);
+ if (mBlendModeFilter != null && getPaint().getColorFilter() == null) {
+ mPaint.setColorFilter(mBlendModeFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
@@ -344,14 +343,16 @@ public class NinePatchDrawable extends Drawable {
@Override
public void setTintList(@Nullable ColorStateList tint) {
mNinePatchState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mNinePatchState.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, tint,
+ mNinePatchState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(@Nullable PorterDuff.Mode tintMode) {
- mNinePatchState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mNinePatchState.mTint, tintMode);
+ public void setTintMode(@Nullable BlendMode blendMode) {
+ mNinePatchState.mBlendMode = blendMode;
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, mNinePatchState.mTint,
+ blendMode);
invalidateSelf();
}
@@ -467,7 +468,7 @@ public class NinePatchDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.NinePatchDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.NinePatchDrawable_tint);
@@ -566,8 +567,9 @@ public class NinePatchDrawable extends Drawable {
@Override
protected boolean onStateChange(int[] stateSet) {
final NinePatchState state = mNinePatchState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint,
+ state.mBlendMode);
return true;
}
@@ -593,7 +595,7 @@ public class NinePatchDrawable extends Drawable {
@UnsupportedAppUsage
NinePatch mNinePatch = null;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
Rect mPadding = null;
Insets mOpticalInsets = Insets.NONE;
float mBaseAlpha = 1.0f;
@@ -628,7 +630,7 @@ public class NinePatchDrawable extends Drawable {
mChangingConfigurations = orig.mChangingConfigurations;
mNinePatch = orig.mNinePatch;
mTint = orig.mTint;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
mPadding = orig.mPadding;
mOpticalInsets = orig.mOpticalInsets;
mBaseAlpha = orig.mBaseAlpha;
@@ -751,7 +753,7 @@ public class NinePatchDrawable extends Drawable {
} else {
mTargetDensity = Drawable.resolveDensity(res, mTargetDensity);
}
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ mBlendModeFilter = updateBlendModeFilter(mBlendModeFilter, state.mTint, state.mBlendMode);
computeBitmapSize();
}
}
diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java
index 7bfb4c38d6c8..b5fe7f9e432d 100644
--- a/graphics/java/android/graphics/drawable/ShapeDrawable.java
+++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java
@@ -24,14 +24,13 @@ import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuff.Mode;
-import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Xfermode;
@@ -75,7 +74,7 @@ import java.io.IOException;
*/
public class ShapeDrawable extends Drawable {
private @NonNull ShapeState mShapeState;
- private PorterDuffColorFilter mTintFilter;
+ private BlendModeColorFilter mBlendModeColorFilter;
private boolean mMutated;
/**
@@ -238,8 +237,8 @@ public class ShapeDrawable extends Drawable {
// only draw shape if it may affect output
if (paint.getAlpha() != 0 || paint.getXfermode() != null || paint.hasShadowLayer()) {
final boolean clearColorFilter;
- if (mTintFilter != null && paint.getColorFilter() == null) {
- paint.setColorFilter(mTintFilter);
+ if (mBlendModeColorFilter != null && paint.getColorFilter() == null) {
+ paint.setColorFilter(mBlendModeColorFilter);
clearColorFilter = true;
} else {
clearColorFilter = false;
@@ -292,14 +291,16 @@ public class ShapeDrawable extends Drawable {
@Override
public void setTintList(ColorStateList tint) {
mShapeState.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, mShapeState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint,
+ mShapeState.mBlendMode);
invalidateSelf();
}
@Override
- public void setTintMode(PorterDuff.Mode tintMode) {
- mShapeState.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, tintMode);
+ public void setTintMode(@NonNull BlendMode blendMode) {
+ mShapeState.mBlendMode = blendMode;
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mShapeState.mTint,
+ blendMode);
invalidateSelf();
}
@@ -352,8 +353,9 @@ public class ShapeDrawable extends Drawable {
@Override
protected boolean onStateChange(int[] stateSet) {
final ShapeState state = mShapeState;
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, state.mTint,
+ state.mBlendMode);
return true;
}
return false;
@@ -475,7 +477,7 @@ public class ShapeDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.ShapeDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.ShapeDrawable_tint);
@@ -540,7 +542,7 @@ public class ShapeDrawable extends Drawable {
int[] mThemeAttrs;
Shape mShape;
ColorStateList mTint;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
Rect mPadding;
int mIntrinsicWidth;
int mIntrinsicHeight;
@@ -573,7 +575,7 @@ public class ShapeDrawable extends Drawable {
}
}
mTint = orig.mTint;
- mTintMode = orig.mTintMode;
+ mBlendMode = orig.mBlendMode;
if (orig.mPadding != null) {
mPadding = new Rect(orig.mPadding);
}
@@ -625,7 +627,8 @@ public class ShapeDrawable extends Drawable {
* after inflating or applying a theme.
*/
private void updateLocalState() {
- mTintFilter = updateTintFilter(mTintFilter, mShapeState.mTint, mShapeState.mTintMode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, mShapeState.mTint,
+ mShapeState.mBlendMode);
}
/**
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 7325b857f02c..43772ec20cf3 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -24,11 +24,13 @@ import android.content.res.GradientColor;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
+import android.graphics.BlendMode;
+import android.graphics.BlendModeColorFilter;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Insets;
import android.graphics.PixelFormat;
-import android.graphics.PorterDuff.Mode;
+import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Rect;
import android.graphics.Shader;
@@ -324,6 +326,8 @@ public class VectorDrawable extends Drawable {
@UnsupportedAppUsage
private PorterDuffColorFilter mTintFilter;
+
+ private BlendModeColorFilter mBlendModeColorFilter;
private ColorFilter mColorFilter;
private boolean mMutated;
@@ -371,7 +375,7 @@ public class VectorDrawable extends Drawable {
mDpiScaledDirty = true;
}
- mTintFilter = updateTintFilter(mTintFilter, mVectorState.mTint, mVectorState.mTintMode);
+ updateColorFilters(mVectorState.mBlendMode, mVectorState.mTint);
}
@Override
@@ -413,7 +417,8 @@ public class VectorDrawable extends Drawable {
}
// Color filters always override tint filters.
- final ColorFilter colorFilter = (mColorFilter == null ? mTintFilter : mColorFilter);
+ final ColorFilter colorFilter = (mColorFilter == null ? mBlendModeColorFilter :
+ mColorFilter);
final long colorFilterNativeInstance = colorFilter == null ? 0 :
colorFilter.getNativeInstance();
boolean canReuseCache = mVectorState.canReuseCache();
@@ -475,17 +480,19 @@ public class VectorDrawable extends Drawable {
final VectorDrawableState state = mVectorState;
if (state.mTint != tint) {
state.mTint = tint;
- mTintFilter = updateTintFilter(mTintFilter, tint, state.mTintMode);
+
+ updateColorFilters(mVectorState.mBlendMode, tint);
invalidateSelf();
}
}
@Override
- public void setTintMode(Mode tintMode) {
+ public void setTintMode(@NonNull BlendMode blendMode) {
final VectorDrawableState state = mVectorState;
- if (state.mTintMode != tintMode) {
- state.mTintMode = tintMode;
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, tintMode);
+ if (state.mBlendMode != blendMode) {
+ state.mBlendMode = blendMode;
+
+ updateColorFilters(state.mBlendMode, state.mTint);
invalidateSelf();
}
}
@@ -515,14 +522,22 @@ public class VectorDrawable extends Drawable {
changed = true;
state.mCacheDirty = true;
}
- if (state.mTint != null && state.mTintMode != null) {
- mTintFilter = updateTintFilter(mTintFilter, state.mTint, state.mTintMode);
+ if (state.mTint != null && state.mBlendMode != null) {
+ BlendMode blendMode = state.mBlendMode;
+ ColorStateList tint = state.mTint;
+ updateColorFilters(blendMode, tint);
changed = true;
}
return changed;
}
+ private void updateColorFilters(@Nullable BlendMode blendMode, ColorStateList tint) {
+ PorterDuff.Mode mode = BlendMode.blendModeToPorterDuffMode(blendMode);
+ mTintFilter = updateTintFilter(mTintFilter, tint, mode);
+ mBlendModeColorFilter = updateBlendModeFilter(mBlendModeColorFilter, tint, blendMode);
+ }
+
@Override
public int getOpacity() {
// We can't tell whether the drawable is fully opaque unless we examine all the pixels,
@@ -737,7 +752,7 @@ public class VectorDrawable extends Drawable {
final int tintMode = a.getInt(R.styleable.VectorDrawable_tintMode, -1);
if (tintMode != -1) {
- state.mTintMode = Drawable.parseTintMode(tintMode, Mode.SRC_IN);
+ state.mBlendMode = Drawable.parseBlendMode(tintMode, BlendMode.SRC_IN);
}
final ColorStateList tint = a.getColorStateList(R.styleable.VectorDrawable_tint);
@@ -911,7 +926,7 @@ public class VectorDrawable extends Drawable {
int[] mThemeAttrs;
@Config int mChangingConfigurations;
ColorStateList mTint = null;
- Mode mTintMode = DEFAULT_TINT_MODE;
+ BlendMode mBlendMode = DEFAULT_BLEND_MODE;
boolean mAutoMirrored;
int mBaseWidth = 0;
@@ -929,7 +944,7 @@ public class VectorDrawable extends Drawable {
// Fields for cache
int[] mCachedThemeAttrs;
ColorStateList mCachedTint;
- Mode mCachedTintMode;
+ BlendMode mCachedBlendMode;
boolean mCachedAutoMirrored;
boolean mCacheDirty;
@@ -970,7 +985,7 @@ public class VectorDrawable extends Drawable {
mThemeAttrs = copy.mThemeAttrs;
mChangingConfigurations = copy.mChangingConfigurations;
mTint = copy.mTint;
- mTintMode = copy.mTintMode;
+ mBlendMode = copy.mBlendMode;
mAutoMirrored = copy.mAutoMirrored;
mRootGroup = new VGroup(copy.mRootGroup, mVGTargetsMap);
createNativeTreeFromCopy(copy, mRootGroup);
@@ -1026,7 +1041,7 @@ public class VectorDrawable extends Drawable {
if (!mCacheDirty
&& mCachedThemeAttrs == mThemeAttrs
&& mCachedTint == mTint
- && mCachedTintMode == mTintMode
+ && mCachedBlendMode == mBlendMode
&& mCachedAutoMirrored == mAutoMirrored) {
return true;
}
@@ -1039,7 +1054,7 @@ public class VectorDrawable extends Drawable {
// likely hit cache miss more, but practically not much difference.
mCachedThemeAttrs = mThemeAttrs;
mCachedTint = mTint;
- mCachedTintMode = mTintMode;
+ mCachedBlendMode = mBlendMode;
mCachedAutoMirrored = mAutoMirrored;
mCacheDirty = false;
}
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index 1836f009f86b..bd1a49205fd5 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -435,8 +435,9 @@ public final class PdfRenderer implements AutoCloseable {
final long transformPtr = transform.native_instance;
synchronized (sPdfiumLock) {
- nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
- contentTop, contentRight, contentBottom, transformPtr, renderMode);
+ nativeRenderPage(mNativeDocument, mNativePage, destination.getNativeInstance(),
+ contentLeft, contentTop, contentRight, contentBottom, transformPtr,
+ renderMode);
}
}
@@ -487,7 +488,7 @@ public final class PdfRenderer implements AutoCloseable {
private static native void nativeClose(long documentPtr);
private static native int nativeGetPageCount(long documentPtr);
private static native boolean nativeScaleForPrinting(long documentPtr);
- private static native void nativeRenderPage(long documentPtr, long pagePtr, Bitmap dest,
+ private static native void nativeRenderPage(long documentPtr, long pagePtr, long bitmapHandle,
int clipLeft, int clipTop, int clipRight, int clipBottom, long transformPtr,
int renderMode);
private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex,
diff --git a/graphics/java/android/graphics/text/MeasuredText.java b/graphics/java/android/graphics/text/MeasuredText.java
index 9db7533044e2..b6d8fa19fca8 100644
--- a/graphics/java/android/graphics/text/MeasuredText.java
+++ b/graphics/java/android/graphics/text/MeasuredText.java
@@ -42,7 +42,7 @@ import libcore.util.NativeAllocationRegistry;
* String text = "Hello, Android.";
* MeasuredText mt = new MeasuredText.Builder(text.toCharArray())
* .appendStyleRun(paint, 7, false) // Use paint for "Hello, "
- * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Hello, "
+ * .appendStyleRun(bigPaint, 8, false) // Use bigPaint for "Android."
* .build();
* </code>
* </pre>