summaryrefslogtreecommitdiffstats
path: root/graphics/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'graphics/java/android')
-rw-r--r--graphics/java/android/graphics/Atlas.java39
-rw-r--r--graphics/java/android/graphics/Bitmap.java105
-rw-r--r--graphics/java/android/graphics/BitmapShader.java5
-rw-r--r--graphics/java/android/graphics/Canvas.java22
-rw-r--r--graphics/java/android/graphics/NinePatch.java16
-rw-r--r--graphics/java/android/graphics/drawable/DrawableContainer.java4
-rw-r--r--graphics/java/android/graphics/drawable/Icon.java482
-rw-r--r--graphics/java/android/graphics/drawable/RippleDrawable.java7
-rw-r--r--graphics/java/android/graphics/pdf/PdfRenderer.java4
9 files changed, 578 insertions, 106 deletions
diff --git a/graphics/java/android/graphics/Atlas.java b/graphics/java/android/graphics/Atlas.java
index 39a5a53..e0a5345 100644
--- a/graphics/java/android/graphics/Atlas.java
+++ b/graphics/java/android/graphics/Atlas.java
@@ -21,10 +21,12 @@ package android.graphics;
*/
public class Atlas {
/**
- * This flag indicates whether the packing algorithm will attempt
- * to rotate entries to make them fit better in the atlas.
+ * WARNING: These flag values are part of the on-disk configuration information,
+ * do not change their values.
*/
- public static final int FLAG_ALLOW_ROTATIONS = 0x1;
+
+ /** DELETED: FLAG_ROTATION = 0x01 */
+
/**
* This flag indicates whether the packing algorithm should leave
* an empty 1 pixel wide border around each bitmap. This border can
@@ -52,9 +54,7 @@ public class Atlas {
/**
* Represents a bitmap packed in the atlas. Each entry has a location in
- * pixels in the atlas and a rotation flag. If the entry was rotated, the
- * bitmap must be rotated by 90 degrees (in either direction as long as
- * the origin remains the same) before being rendered into the atlas.
+ * pixels in the atlas and a rotation flag.
*/
public static class Entry {
/**
@@ -65,11 +65,6 @@ public class Atlas {
* Location, in pixels, of the bitmap on the Y axis in the atlas.
*/
public int y;
-
- /**
- * If true, the bitmap must be rotated 90 degrees in the atlas.
- */
- public boolean rotated;
}
private final Policy mPolicy;
@@ -239,7 +234,6 @@ public class Atlas {
private final SplitDecision mSplitDecision;
- private final boolean mAllowRotation;
private final int mPadding;
/**
@@ -263,7 +257,6 @@ public class Atlas {
}
SlicePolicy(int width, int height, int flags, SplitDecision splitDecision) {
- mAllowRotation = (flags & FLAG_ALLOW_ROTATIONS) != 0;
mPadding = (flags & FLAG_ADD_PADDING) != 0 ? 1 : 0;
// The entire atlas is empty at first, minus padding
@@ -360,26 +353,9 @@ public class Atlas {
*
* @return True if the rectangle was packed in the atlas, false otherwise
*/
- @SuppressWarnings("SuspiciousNameCombination")
private boolean insert(Cell cell, Cell prev, int width, int height, Entry entry) {
- boolean rotated = false;
-
- // If the rectangle doesn't fit we'll try to rotate it
- // if possible before giving up
if (cell.width < width || cell.height < height) {
- if (mAllowRotation) {
- if (cell.width < height || cell.height < width) {
- return false;
- }
-
- // Rotate the rectangle
- int temp = width;
- width = height;
- height = temp;
- rotated = true;
- } else {
- return false;
- }
+ return false;
}
// Remaining free space after packing the rectangle
@@ -433,7 +409,6 @@ public class Atlas {
// Return the location and rotation of the packed rectangle
entry.x = cell.x;
entry.y = cell.y;
- entry.rotated = rotated;
return true;
}
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index e2f7799..bd52848 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -41,13 +41,13 @@ public final class Bitmap implements Parcelable {
*/
public static final int DENSITY_NONE = 0;
- private final long mSkBitmapPtr;
-
/**
* Backing buffer for the Bitmap.
*/
private byte[] mBuffer;
+ // Convenience for JNI access
+ private final long mNativePtr;
private final BitmapFinalizer mFinalizer;
private final boolean mIsMutable;
@@ -115,17 +115,16 @@ public final class Bitmap implements Parcelable {
mRequestPremultiplied = requestPremultiplied;
mBuffer = buffer;
- // we delete this in our finalizer
- mSkBitmapPtr = nativeBitmap;
-
mNinePatchChunk = ninePatchChunk;
mNinePatchInsets = ninePatchInsets;
if (density >= 0) {
mDensity = density;
}
- int nativeAllocationByteCount = buffer == null ? getByteCount() : 0;
- mFinalizer = new BitmapFinalizer(nativeBitmap, nativeAllocationByteCount);
+ mNativePtr = nativeBitmap;
+ mFinalizer = new BitmapFinalizer(nativeBitmap);
+ int nativeAllocationByteCount = (buffer == null ? getByteCount() : 0);
+ mFinalizer.setNativeAllocationByteCount(nativeAllocationByteCount);
}
/**
@@ -223,8 +222,8 @@ public final class Bitmap implements Parcelable {
throw new IllegalStateException("native-backed bitmaps may not be reconfigured");
}
- nativeReconfigure(mSkBitmapPtr, width, height, config.nativeInt, mBuffer.length,
- mRequestPremultiplied);
+ nativeReconfigure(mFinalizer.mNativeBitmap, width, height, config.nativeInt,
+ mBuffer.length, mRequestPremultiplied);
mWidth = width;
mHeight = height;
}
@@ -301,7 +300,7 @@ public final class Bitmap implements Parcelable {
*/
public void recycle() {
if (!mRecycled && mFinalizer.mNativeBitmap != 0) {
- if (nativeRecycle(mSkBitmapPtr)) {
+ if (nativeRecycle(mFinalizer.mNativeBitmap)) {
// return value indicates whether native pixel object was actually recycled.
// false indicates that it is still in use at the native level and these
// objects should not be collected now. They will be collected later when the
@@ -331,7 +330,8 @@ public final class Bitmap implements Parcelable {
* @return The current generation ID for this bitmap.
*/
public int getGenerationId() {
- return nativeGenerationId(mSkBitmapPtr);
+ if (mRecycled) return 0;
+ return nativeGenerationId(mFinalizer.mNativeBitmap);
}
/**
@@ -487,7 +487,7 @@ public final class Bitmap implements Parcelable {
throw new RuntimeException("Buffer not large enough for pixels");
}
- nativeCopyPixelsToBuffer(mSkBitmapPtr, dst);
+ nativeCopyPixelsToBuffer(mFinalizer.mNativeBitmap, dst);
// now update the buffer's position
int position = dst.position();
@@ -527,7 +527,7 @@ public final class Bitmap implements Parcelable {
throw new RuntimeException("Buffer not large enough for pixels");
}
- nativeCopyPixelsFromBuffer(mSkBitmapPtr, src);
+ nativeCopyPixelsFromBuffer(mFinalizer.mNativeBitmap, src);
// now update the buffer's position
int position = src.position();
@@ -549,7 +549,7 @@ public final class Bitmap implements Parcelable {
*/
public Bitmap copy(Config config, boolean isMutable) {
checkRecycled("Can't copy a recycled bitmap");
- Bitmap b = nativeCopy(mSkBitmapPtr, config.nativeInt, isMutable);
+ Bitmap b = nativeCopy(mFinalizer.mNativeBitmap, config.nativeInt, isMutable);
if (b != null) {
b.setPremultiplied(mRequestPremultiplied);
b.mDensity = mDensity;
@@ -810,7 +810,7 @@ public final class Bitmap implements Parcelable {
}
bm.setHasAlpha(hasAlpha);
if (config == Config.ARGB_8888 && !hasAlpha) {
- nativeErase(bm.mSkBitmapPtr, 0xff000000);
+ nativeErase(bm.mFinalizer.mNativeBitmap, 0xff000000);
}
// No need to initialize the bitmap to zeroes with other configs;
// it is backed by a VM byte array which is by definition preinitialized
@@ -1000,8 +1000,8 @@ public final class Bitmap implements Parcelable {
throw new IllegalArgumentException("quality must be 0..100");
}
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, "Bitmap.compress");
- boolean result = nativeCompress(mSkBitmapPtr, format.nativeInt, quality,
- stream, new byte[WORKING_COMPRESS_STORAGE]);
+ boolean result = nativeCompress(mFinalizer.mNativeBitmap, format.nativeInt,
+ quality, stream, new byte[WORKING_COMPRESS_STORAGE]);
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
return result;
}
@@ -1041,7 +1041,8 @@ public final class Bitmap implements Parcelable {
* @see BitmapFactory.Options#inPremultiplied
*/
public final boolean isPremultiplied() {
- return nativeIsPremultiplied(mSkBitmapPtr);
+ if (mRecycled) return false;
+ return nativeIsPremultiplied(mFinalizer.mNativeBitmap);
}
/**
@@ -1065,8 +1066,9 @@ public final class Bitmap implements Parcelable {
* @see BitmapFactory.Options#inPremultiplied
*/
public final void setPremultiplied(boolean premultiplied) {
+ checkRecycled("setPremultiplied called on a recycled bitmap");
mRequestPremultiplied = premultiplied;
- nativeSetPremultiplied(mSkBitmapPtr, premultiplied);
+ nativeSetPremultiplied(mFinalizer.mNativeBitmap, premultiplied);
}
/** Returns the bitmap's width */
@@ -1158,7 +1160,7 @@ public final class Bitmap implements Parcelable {
* @return number of bytes between rows of the native bitmap pixels.
*/
public final int getRowBytes() {
- return nativeRowBytes(mSkBitmapPtr);
+ return nativeRowBytes(mFinalizer.mNativeBitmap);
}
/**
@@ -1201,7 +1203,8 @@ public final class Bitmap implements Parcelable {
* that config, otherwise return null.
*/
public final Config getConfig() {
- return Config.nativeToConfig(nativeConfig(mSkBitmapPtr));
+ if (mRecycled) return Config.ARGB_8888;
+ return Config.nativeToConfig(nativeConfig(mFinalizer.mNativeBitmap));
}
/** Returns true if the bitmap's config supports per-pixel alpha, and
@@ -1213,7 +1216,8 @@ public final class Bitmap implements Parcelable {
* it will return true by default.
*/
public final boolean hasAlpha() {
- return nativeHasAlpha(mSkBitmapPtr);
+ if (mRecycled) return false;
+ return nativeHasAlpha(mFinalizer.mNativeBitmap);
}
/**
@@ -1227,7 +1231,8 @@ public final class Bitmap implements Parcelable {
* non-opaque per-pixel alpha values.
*/
public void setHasAlpha(boolean hasAlpha) {
- nativeSetHasAlpha(mSkBitmapPtr, hasAlpha, mRequestPremultiplied);
+ checkRecycled("setHasAlpha called on a recycled bitmap");
+ nativeSetHasAlpha(mFinalizer.mNativeBitmap, hasAlpha, mRequestPremultiplied);
}
/**
@@ -1248,7 +1253,8 @@ public final class Bitmap implements Parcelable {
* @see #setHasMipMap(boolean)
*/
public final boolean hasMipMap() {
- return nativeHasMipMap(mSkBitmapPtr);
+ if (mRecycled) return false;
+ return nativeHasMipMap(mFinalizer.mNativeBitmap);
}
/**
@@ -1272,7 +1278,8 @@ public final class Bitmap implements Parcelable {
* @see #hasMipMap()
*/
public final void setHasMipMap(boolean hasMipMap) {
- nativeSetHasMipMap(mSkBitmapPtr, hasMipMap);
+ checkRecycled("setHasMipMap called on a recycled bitmap");
+ nativeSetHasMipMap(mFinalizer.mNativeBitmap, hasMipMap);
}
/**
@@ -1285,7 +1292,7 @@ public final class Bitmap implements Parcelable {
if (!isMutable()) {
throw new IllegalStateException("cannot erase immutable bitmaps");
}
- nativeErase(mSkBitmapPtr, c);
+ nativeErase(mFinalizer.mNativeBitmap, c);
}
/**
@@ -1302,7 +1309,7 @@ public final class Bitmap implements Parcelable {
public int getPixel(int x, int y) {
checkRecycled("Can't call getPixel() on a recycled bitmap");
checkPixelAccess(x, y);
- return nativeGetPixel(mSkBitmapPtr, x, y);
+ return nativeGetPixel(mFinalizer.mNativeBitmap, x, y);
}
/**
@@ -1335,7 +1342,7 @@ public final class Bitmap implements Parcelable {
return; // nothing to do
}
checkPixelsAccess(x, y, width, height, offset, stride, pixels);
- nativeGetPixels(mSkBitmapPtr, pixels, offset, stride,
+ nativeGetPixels(mFinalizer.mNativeBitmap, pixels, offset, stride,
x, y, width, height);
}
@@ -1416,7 +1423,7 @@ public final class Bitmap implements Parcelable {
throw new IllegalStateException();
}
checkPixelAccess(x, y);
- nativeSetPixel(mSkBitmapPtr, x, y, color);
+ nativeSetPixel(mFinalizer.mNativeBitmap, x, y, color);
}
/**
@@ -1452,7 +1459,7 @@ public final class Bitmap implements Parcelable {
return; // nothing to do
}
checkPixelsAccess(x, y, width, height, offset, stride, pixels);
- nativeSetPixels(mSkBitmapPtr, pixels, offset, stride,
+ nativeSetPixels(mFinalizer.mNativeBitmap, pixels, offset, stride,
x, y, width, height);
}
@@ -1490,7 +1497,7 @@ public final class Bitmap implements Parcelable {
*/
public void writeToParcel(Parcel p, int flags) {
checkRecycled("Can't parcel a recycled bitmap");
- if (!nativeWriteToParcel(mSkBitmapPtr, mIsMutable, mDensity, p)) {
+ if (!nativeWriteToParcel(mFinalizer.mNativeBitmap, mIsMutable, mDensity, p)) {
throw new RuntimeException("native writeToParcel failed");
}
}
@@ -1536,7 +1543,7 @@ public final class Bitmap implements Parcelable {
public Bitmap extractAlpha(Paint paint, int[] offsetXY) {
checkRecycled("Can't extractAlpha on a recycled bitmap");
long nativePaint = paint != null ? paint.getNativeInstance() : 0;
- Bitmap bm = nativeExtractAlpha(mSkBitmapPtr, nativePaint, offsetXY);
+ Bitmap bm = nativeExtractAlpha(mFinalizer.mNativeBitmap, nativePaint, offsetXY);
if (bm == null) {
throw new RuntimeException("Failed to extractAlpha on Bitmap");
}
@@ -1550,7 +1557,8 @@ public final class Bitmap implements Parcelable {
* If other is null, return false.
*/
public boolean sameAs(Bitmap other) {
- return this == other || (other != null && nativeSameAs(mSkBitmapPtr, other.mSkBitmapPtr));
+ return this == other || (other != null
+ && nativeSameAs(mFinalizer.mNativeBitmap, other.mFinalizer.mNativeBitmap));
}
/**
@@ -1565,12 +1573,18 @@ public final class Bitmap implements Parcelable {
* and therefore is harmless.
*/
public void prepareToDraw() {
- nativePrepareToDraw(mSkBitmapPtr);
+ // TODO: Consider having this start an async upload?
+ // With inPurgeable no-op'd there's currently no use for this
+ // method, but it could have interesting future uses.
}
- /** @hide */
- public final long getSkBitmap() {
- return mSkBitmapPtr;
+ /**
+ * Refs the underlying SkPixelRef and returns a pointer to it.
+ *
+ * @hide
+ * */
+ public final long refSkPixelRef() {
+ return nativeRefPixelRef(mNativePtr);
}
private static class BitmapFinalizer {
@@ -1578,12 +1592,17 @@ public final class Bitmap implements Parcelable {
// Native memory allocated for the duration of the Bitmap,
// if pixel data allocated into native memory, instead of java byte[]
- private final int mNativeAllocationByteCount;
+ private int mNativeAllocationByteCount;
- BitmapFinalizer(long nativeBitmap, int nativeAllocationByteCount) {
+ BitmapFinalizer(long nativeBitmap) {
mNativeBitmap = nativeBitmap;
- mNativeAllocationByteCount = nativeAllocationByteCount;
+ }
+ public void setNativeAllocationByteCount(int nativeByteCount) {
+ if (mNativeAllocationByteCount != 0) {
+ VMRuntime.getRuntime().registerNativeFree(mNativeAllocationByteCount);
+ }
+ mNativeAllocationByteCount = nativeByteCount;
if (mNativeAllocationByteCount != 0) {
VMRuntime.getRuntime().registerNativeAllocation(mNativeAllocationByteCount);
}
@@ -1596,9 +1615,7 @@ public final class Bitmap implements Parcelable {
} catch (Throwable t) {
// Ignore
} finally {
- if (mNativeAllocationByteCount != 0) {
- VMRuntime.getRuntime().registerNativeFree(mNativeAllocationByteCount);
- }
+ setNativeAllocationByteCount(0);
nativeDestructor(mNativeBitmap);
mNativeBitmap = 0;
}
@@ -1650,7 +1667,6 @@ public final class Bitmap implements Parcelable {
long nativePaint,
int[] offsetXY);
- private static native void nativePrepareToDraw(long nativeBitmap);
private static native boolean nativeHasAlpha(long nativeBitmap);
private static native boolean nativeIsPremultiplied(long nativeBitmap);
private static native void nativeSetPremultiplied(long nativeBitmap,
@@ -1661,4 +1677,5 @@ public final class Bitmap implements Parcelable {
private static native boolean nativeHasMipMap(long nativeBitmap);
private static native void nativeSetHasMipMap(long nativeBitmap, boolean hasMipMap);
private static native boolean nativeSameAs(long nativeBitmap0, long nativeBitmap1);
+ private static native long nativeRefPixelRef(long nativeBitmap);
}
diff --git a/graphics/java/android/graphics/BitmapShader.java b/graphics/java/android/graphics/BitmapShader.java
index f2f890e..bd74bc8 100644
--- a/graphics/java/android/graphics/BitmapShader.java
+++ b/graphics/java/android/graphics/BitmapShader.java
@@ -42,8 +42,7 @@ public class BitmapShader extends Shader {
mBitmap = bitmap;
mTileX = tileX;
mTileY = tileY;
- final long b = bitmap.getSkBitmap();
- init(nativeCreate(b, tileX.nativeInt, tileY.nativeInt));
+ init(nativeCreate(bitmap, tileX.nativeInt, tileY.nativeInt));
}
/**
@@ -56,6 +55,6 @@ public class BitmapShader extends Shader {
return copy;
}
- private static native long nativeCreate(long native_bitmap, int shaderTileModeX,
+ private static native long nativeCreate(Bitmap bitmap, int shaderTileModeX,
int shaderTileModeY);
}
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 9fe8e0c..392a5b6 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -81,10 +81,6 @@ public class Canvas {
*/
protected int mScreenDensity = Bitmap.DENSITY_NONE;
- // Used by native code
- @SuppressWarnings("UnusedDeclaration")
- private int mSurfaceFormat;
-
// Maximum bitmap size as defined in Skia's native code
// (see SkCanvas.cpp, SkDraw.cpp)
private static final int MAXMIMUM_BITMAP_SIZE = 32766;
@@ -1327,7 +1323,7 @@ public class Canvas {
*/
public void drawBitmap(@NonNull Bitmap bitmap, float left, float top, @Nullable Paint paint) {
throwIfCannotDraw(bitmap);
- native_drawBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), left, top,
+ native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top,
paint != null ? paint.getNativeInstance() : 0, mDensity, mScreenDensity, bitmap.mDensity);
}
@@ -1373,7 +1369,7 @@ public class Canvas {
bottom = src.bottom;
}
- native_drawBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), left, top, right, bottom,
+ native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
bitmap.mDensity);
}
@@ -1420,7 +1416,7 @@ public class Canvas {
bottom = src.bottom;
}
- native_drawBitmap(mNativeCanvasWrapper, bitmap.getSkBitmap(), left, top, right, bottom,
+ native_drawBitmap(mNativeCanvasWrapper, bitmap, left, top, right, bottom,
dst.left, dst.top, dst.right, dst.bottom, nativePaint, mScreenDensity,
bitmap.mDensity);
}
@@ -1501,7 +1497,7 @@ public class Canvas {
* @param paint May be null. The paint used to draw the bitmap
*/
public void drawBitmap(@NonNull Bitmap bitmap, @NonNull Matrix matrix, @Nullable Paint paint) {
- nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap.getSkBitmap(), matrix.ni(),
+ nativeDrawBitmapMatrix(mNativeCanvasWrapper, bitmap, matrix.ni(),
paint != null ? paint.getNativeInstance() : 0);
}
@@ -1556,7 +1552,7 @@ public class Canvas {
// no mul by 2, since we need only 1 color per vertex
checkRange(colors.length, colorOffset, count);
}
- nativeDrawBitmapMesh(mNativeCanvasWrapper, bitmap.getSkBitmap(), meshWidth, meshHeight,
+ nativeDrawBitmapMesh(mNativeCanvasWrapper, bitmap, meshWidth, meshHeight,
verts, vertOffset, colors, colorOffset,
paint != null ? paint.getNativeInstance() : 0);
}
@@ -2066,13 +2062,13 @@ public class Canvas {
private static native void native_drawPath(long nativeCanvas,
long nativePath,
long nativePaint);
- private native void native_drawBitmap(long nativeCanvas, long nativeBitmap,
+ private native void native_drawBitmap(long nativeCanvas, Bitmap bitmap,
float left, float top,
long nativePaintOrZero,
int canvasDensity,
int screenDensity,
int bitmapDensity);
- private native void native_drawBitmap(long nativeCanvas, long nativeBitmap,
+ private native void native_drawBitmap(long nativeCanvas, Bitmap bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
long nativePaintOrZero, int screenDensity, int bitmapDensity);
@@ -2082,11 +2078,11 @@ public class Canvas {
boolean hasAlpha,
long nativePaintOrZero);
private static native void nativeDrawBitmapMatrix(long nativeCanvas,
- long nativeBitmap,
+ Bitmap bitmap,
long nativeMatrix,
long nativePaint);
private static native void nativeDrawBitmapMesh(long nativeCanvas,
- long nativeBitmap,
+ Bitmap bitmap,
int meshWidth, int meshHeight,
float[] verts, int vertOffset,
int[] colors, int colorOffset,
diff --git a/graphics/java/android/graphics/NinePatch.java b/graphics/java/android/graphics/NinePatch.java
index 9c4299a..21a212a 100644
--- a/graphics/java/android/graphics/NinePatch.java
+++ b/graphics/java/android/graphics/NinePatch.java
@@ -98,7 +98,7 @@ public class NinePatch {
public NinePatch(Bitmap bitmap, byte[] chunk, String srcName) {
mBitmap = bitmap;
mSrcName = srcName;
- mNativeChunk = validateNinePatchChunk(mBitmap.getSkBitmap(), chunk);
+ mNativeChunk = validateNinePatchChunk(chunk);
}
/**
@@ -199,12 +199,12 @@ public class NinePatch {
}
void drawSoftware(Canvas canvas, RectF location, Paint paint) {
- nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap.getSkBitmap(), mNativeChunk,
+ nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap, mNativeChunk,
paint != null ? paint.getNativeInstance() : 0, canvas.mDensity, mBitmap.mDensity);
}
void drawSoftware(Canvas canvas, Rect location, Paint paint) {
- nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap.getSkBitmap(), mNativeChunk,
+ nativeDraw(canvas.getNativeCanvasWrapper(), location, mBitmap, mNativeChunk,
paint != null ? paint.getNativeInstance() : 0, canvas.mDensity, mBitmap.mDensity);
}
@@ -252,7 +252,7 @@ public class NinePatch {
* that are transparent.
*/
public final Region getTransparentRegion(Rect bounds) {
- long r = nativeGetTransparentRegion(mBitmap.getSkBitmap(), mNativeChunk, bounds);
+ long r = nativeGetTransparentRegion(mBitmap, mNativeChunk, bounds);
return r != 0 ? new Region(r) : null;
}
@@ -271,11 +271,11 @@ public class NinePatch {
* If validation is successful, this method returns a native Res_png_9patch*
* object used by the renderers.
*/
- private static native long validateNinePatchChunk(long bitmap, byte[] chunk);
+ private static native long validateNinePatchChunk(byte[] chunk);
private static native void nativeFinalize(long chunk);
- private static native void nativeDraw(long canvas_instance, RectF loc, long bitmap_instance,
+ private static native void nativeDraw(long canvas_instance, RectF loc, Bitmap bitmap_instance,
long c, long paint_instance_or_null, int destDensity, int srcDensity);
- private static native void nativeDraw(long canvas_instance, Rect loc, long bitmap_instance,
+ private static native void nativeDraw(long canvas_instance, Rect loc, Bitmap bitmap_instance,
long c, long paint_instance_or_null, int destDensity, int srcDensity);
- private static native long nativeGetTransparentRegion(long bitmap, long chunk, Rect location);
+ private static native long nativeGetTransparentRegion(Bitmap bitmap, long chunk, Rect location);
}
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index b03fe3a..4a06805 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -295,9 +295,9 @@ public class DrawableContainer extends Drawable implements Drawable.Callback {
@Override
public void setHotspotBounds(int left, int top, int right, int bottom) {
if (mHotspotBounds == null) {
- mHotspotBounds = new Rect(left, top, bottom, right);
+ mHotspotBounds = new Rect(left, top, right, bottom);
} else {
- mHotspotBounds.set(left, top, bottom, right);
+ mHotspotBounds.set(left, top, right, bottom);
}
if (mCurrDrawable != null) {
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
new file mode 100644
index 0000000..47a1f77
--- /dev/null
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -0,0 +1,482 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.graphics.drawable;
+
+import android.annotation.DrawableRes;
+import android.content.ContentResolver;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.lang.IllegalArgumentException;
+import java.lang.Override;
+
+/**
+ * An umbrella container for several serializable graphics representations, including Bitmaps,
+ * compressed bitmap images (e.g. JPG or PNG), and drawable resources (including vectors).
+ *
+ * <a href="https://developer.android.com/training/displaying-bitmaps/index.html">Much ink</a>
+ * has been spilled on the best way to load images, and many clients may have different needs when
+ * it comes to threading and fetching. This class is therefore focused on encapsulation rather than
+ * behavior.
+ */
+
+public final class Icon implements Parcelable {
+ private static final String TAG = "Icon";
+
+ private static final int TYPE_BITMAP = 1;
+ private static final int TYPE_RESOURCE = 2;
+ private static final int TYPE_DATA = 3;
+ private static final int TYPE_URI = 4;
+
+ private final int mType;
+
+ // To avoid adding unnecessary overhead, we have a few basic objects that get repurposed
+ // based on the value of mType.
+
+ // TYPE_BITMAP: Bitmap
+ // TYPE_RESOURCE: Resources
+ // TYPE_DATA: DataBytes
+ private Object mObj1;
+
+ // TYPE_RESOURCE: package name
+ // TYPE_URI: uri string
+ private String mString1;
+
+ // TYPE_RESOURCE: resId
+ // TYPE_DATA: data length
+ private int mInt1;
+
+ // TYPE_DATA: data offset
+ private int mInt2;
+
+ // Internal accessors for different mType variants
+ private Bitmap getBitmap() {
+ if (mType != TYPE_BITMAP) {
+ throw new IllegalStateException("called getBitmap() on " + this);
+ }
+ return (Bitmap) mObj1;
+ }
+
+ private int getDataLength() {
+ if (mType != TYPE_DATA) {
+ throw new IllegalStateException("called getDataLength() on " + this);
+ }
+ synchronized (this) {
+ return mInt1;
+ }
+ }
+
+ private int getDataOffset() {
+ if (mType != TYPE_DATA) {
+ throw new IllegalStateException("called getDataOffset() on " + this);
+ }
+ synchronized (this) {
+ return mInt2;
+ }
+ }
+
+ private byte[] getDataBytes() {
+ if (mType != TYPE_DATA) {
+ throw new IllegalStateException("called getDataBytes() on " + this);
+ }
+ synchronized (this) {
+ return (byte[]) mObj1;
+ }
+ }
+
+ private Resources getResources() {
+ if (mType != TYPE_RESOURCE) {
+ throw new IllegalStateException("called getResources() on " + this);
+ }
+ return (Resources) mObj1;
+ }
+
+ private String getResPackage() {
+ if (mType != TYPE_RESOURCE) {
+ throw new IllegalStateException("called getResPackage() on " + this);
+ }
+ return mString1;
+ }
+
+ private int getResId() {
+ if (mType != TYPE_RESOURCE) {
+ throw new IllegalStateException("called getResId() on " + this);
+ }
+ return mInt1;
+ }
+
+ private String getUriString() {
+ if (mType != TYPE_URI) {
+ throw new IllegalStateException("called getUriString() on " + this);
+ }
+ return mString1;
+ }
+
+ private Uri getUri() {
+ return Uri.parse(getUriString());
+ }
+
+ // Convert a int32 into a four-char string
+ private static final String typeToString(int x) {
+ switch (x) {
+ case TYPE_BITMAP: return "BITMAP";
+ case TYPE_DATA: return "DATA";
+ case TYPE_RESOURCE: return "RESOURCE";
+ case TYPE_URI: return "URI";
+ default: return "UNKNOWN";
+ }
+ }
+
+ /**
+ * Invokes {@link #loadDrawable(Context)} on the given {@link android.os.Handler Handler}
+ * and then sends <code>andThen</code> to the same Handler when finished.
+ *
+ * @param context {@link android.content.Context Context} in which to load the drawable; see
+ * {@link #loadDrawable(Context)}
+ * @param andThen {@link android.os.Message} to send to its target once the drawable
+ * is available. The {@link android.os.Message#obj obj}
+ * property is populated with the Drawable.
+ */
+ public void loadDrawableAsync(Context context, Message andThen) {
+ if (andThen.getTarget() == null) {
+ throw new IllegalArgumentException("callback message must have a target handler");
+ }
+ new LoadDrawableTask(context, andThen).runAsync();
+ }
+
+ /**
+ * Invokes {@link #loadDrawable(Context)} on a background thread
+ * and then runs <code>andThen</code> on the UI thread when finished.
+ *
+ * @param context {@link android.content.Context Context} in which to load the drawable; see
+ * {@link #loadDrawable(Context)}
+ * @param handler {@link android.os.Handler} on which to run <code>andThen</code>.
+ * @param listener a callback to run on the provided
+ * Handler once the drawable is available.
+ */
+ public void loadDrawableAsync(Context context, Handler handler,
+ final OnDrawableLoadedListener listener) {
+ new LoadDrawableTask(context, handler, listener).runAsync();
+ }
+
+ /**
+ * Returns a Drawable that can be used to draw the image inside this Icon, constructing it
+ * if necessary. Depending on the type of image, this may not be something you want to do on
+ * the UI thread, so consider using
+ * {@link #loadDrawableAsync(Context, Message) loadDrawableAsync} instead.
+ *
+ * @param context {@link android.content.Context Context} in which to load the drawable; used
+ * to access {@link android.content.res.Resources Resources}, for example.
+ * @return A fresh instance of a drawable for this image, yours to keep.
+ */
+ public Drawable loadDrawable(Context context) {
+ switch (mType) {
+ case TYPE_BITMAP:
+ return new BitmapDrawable(context.getResources(), getBitmap());
+ case TYPE_RESOURCE:
+ if (getResources() == null) {
+ if (getResPackage() == null || "android".equals(getResPackage())) {
+ mObj1 = Resources.getSystem();
+ } else {
+ final PackageManager pm = context.getPackageManager();
+ try {
+ mObj1 = pm.getResourcesForApplication(getResPackage());
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.e(TAG,
+ String.format("Unable to find package '%s'", getResPackage()),
+ e);
+ break;
+ }
+ }
+ }
+ return getResources().getDrawable(getResId(), context.getTheme());
+ case TYPE_DATA:
+ return new BitmapDrawable(context.getResources(),
+ BitmapFactory.decodeByteArray(getDataBytes(), getDataOffset(), getDataLength())
+ );
+ case TYPE_URI:
+ final Uri uri = getUri();
+ final String scheme = uri.getScheme();
+ InputStream is = null;
+ if (ContentResolver.SCHEME_CONTENT.equals(scheme)
+ || ContentResolver.SCHEME_FILE.equals(scheme)) {
+ try {
+ is = context.getContentResolver().openInputStream(uri);
+ } catch (Exception e) {
+ Log.w(TAG, "Unable to load image from URI: " + uri, e);
+ }
+ } else {
+ try {
+ is = new FileInputStream(new File(mString1));
+ } catch (FileNotFoundException e) {
+ Log.w(TAG, "Unable to load image from path: " + uri, e);
+ }
+ }
+ if (is != null) {
+ return new BitmapDrawable(context.getResources(),
+ BitmapFactory.decodeStream(is));
+ }
+ break;
+ }
+ return null;
+ }
+
+ private Icon(int mType) {
+ this.mType = mType;
+ }
+
+ /**
+ * Create a Icon pointing to a drawable resource.
+ * @param res Resources for a package containing the resource in question
+ * @param resid ID of the drawable resource
+ */
+ public static Icon createWithResource(Resources res, @DrawableRes int resid) {
+ final Icon rep = new Icon(TYPE_RESOURCE);
+ rep.mObj1 = res;
+ rep.mInt1 = resid;
+ rep.mString1 = res.getResourcePackageName(resid);
+ return rep;
+ }
+
+ /**
+ * Create a Icon pointing to a bitmap in memory.
+ * @param bits A valid {@link android.graphics.Bitmap} object
+ */
+ public static Icon createWithBitmap(Bitmap bits) {
+ final Icon rep = new Icon(TYPE_BITMAP);
+ rep.mObj1 = bits;
+ return rep;
+ }
+
+ /**
+ * Create a Icon pointing to a compressed bitmap stored in a byte array.
+ * @param data Byte array storing compressed bitmap data of a type that
+ * {@link android.graphics.BitmapFactory}
+ * can decode (see {@link android.graphics.Bitmap.CompressFormat}).
+ * @param offset Offset into <code>data</code> at which the bitmap data starts
+ * @param length Length of the bitmap data
+ */
+ public static Icon createWithData(byte[] data, int offset, int length) {
+ final Icon rep = new Icon(TYPE_DATA);
+ rep.mObj1 = data;
+ rep.mInt1 = length;
+ rep.mInt2 = offset;
+ return rep;
+ }
+
+ /**
+ * Create a Icon pointing to a content specified by URI.
+ *
+ * @param uri A uri referring to local content:// or file:// image data.
+ */
+ public static Icon createWithContentUri(String uri) {
+ final Icon rep = new Icon(TYPE_URI);
+ rep.mString1 = uri;
+ return rep;
+ }
+
+ /**
+ * Create a Icon pointing to a content specified by URI.
+ *
+ * @param uri A uri referring to local content:// or file:// image data.
+ */
+ public static Icon createWithContentUri(Uri uri) {
+ final Icon rep = new Icon(TYPE_URI);
+ rep.mString1 = uri.toString();
+ return rep;
+ }
+
+ /**
+ * Create a Icon pointing to
+ *
+ * @param path A path to a file that contains compressed bitmap data of
+ * a type that {@link android.graphics.BitmapFactory} can decode.
+ */
+ public static Icon createWithFilePath(String path) {
+ final Icon rep = new Icon(TYPE_URI);
+ rep.mString1 = path;
+ return rep;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("Icon(typ=").append(typeToString(mType));
+ switch (mType) {
+ case TYPE_BITMAP:
+ sb.append(" size=")
+ .append(getBitmap().getWidth())
+ .append("x")
+ .append(getBitmap().getHeight());
+ break;
+ case TYPE_RESOURCE:
+ sb.append(" pkg=")
+ .append(getResPackage())
+ .append(" id=")
+ .append(String.format("%08x", getResId()));
+ break;
+ case TYPE_DATA:
+ sb.append(" len=").append(getDataLength());
+ if (getDataOffset() != 0) {
+ sb.append(" off=").append(getDataOffset());
+ }
+ break;
+ case TYPE_URI:
+ sb.append(" uri=").append(getUriString());
+ break;
+ }
+ sb.append(")");
+ return sb.toString();
+ }
+
+ /**
+ * Parcelable interface
+ */
+ public int describeContents() {
+ return (mType == TYPE_BITMAP || mType == TYPE_DATA)
+ ? Parcelable.CONTENTS_FILE_DESCRIPTOR : 0;
+ }
+
+ // ===== Parcelable interface ======
+
+ private Icon(Parcel in) {
+ this(in.readInt());
+ switch (mType) {
+ case TYPE_BITMAP:
+ final Bitmap bits = Bitmap.CREATOR.createFromParcel(in);
+ mObj1 = bits;
+ break;
+ case TYPE_RESOURCE:
+ final String pkg = in.readString();
+ final int resId = in.readInt();
+ mString1 = pkg;
+ mInt1 = resId;
+ break;
+ case TYPE_DATA:
+ final int len = in.readInt();
+ final byte[] a = in.readBlob();
+ if (len != a.length) {
+ throw new RuntimeException("internal unparceling error: blob length ("
+ + a.length + ") != expected length (" + len + ")");
+ }
+ mInt1 = len;
+ mObj1 = a;
+ break;
+ case TYPE_URI:
+ final String uri = in.readString();
+ mString1 = uri;
+ break;
+ default:
+ throw new RuntimeException("invalid "
+ + this.getClass().getSimpleName() + " type in parcel: " + mType);
+ }
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ switch (mType) {
+ case TYPE_BITMAP:
+ final Bitmap bits = getBitmap();
+ dest.writeInt(TYPE_BITMAP);
+ getBitmap().writeToParcel(dest, flags);
+ break;
+ case TYPE_RESOURCE:
+ dest.writeInt(TYPE_RESOURCE);
+ dest.writeString(getResPackage());
+ dest.writeInt(getResId());
+ break;
+ case TYPE_DATA:
+ dest.writeInt(TYPE_DATA);
+ dest.writeInt(getDataLength());
+ dest.writeBlob(getDataBytes(), getDataOffset(), getDataLength());
+ break;
+ case TYPE_URI:
+ dest.writeInt(TYPE_URI);
+ dest.writeString(getUriString());
+ break;
+ }
+ }
+
+ public static final Parcelable.Creator<Icon> CREATOR
+ = new Parcelable.Creator<Icon>() {
+ public Icon createFromParcel(Parcel in) {
+ return new Icon(in);
+ }
+
+ public Icon[] newArray(int size) {
+ return new Icon[size];
+ }
+ };
+
+ /**
+ * Implement this interface to receive notification when
+ * {@link #loadDrawableAsync(Context, Handler, OnDrawableLoadedListener) loadDrawableAsync}
+ * is finished and your Drawable is ready.
+ */
+ public interface OnDrawableLoadedListener {
+ void onDrawableLoaded(Drawable d);
+ }
+
+ /**
+ * Wrapper around loadDrawable that does its work on a pooled thread and then
+ * fires back the given (targeted) Message.
+ */
+ private class LoadDrawableTask implements Runnable {
+ final Context mContext;
+ final Message mMessage;
+
+ public LoadDrawableTask(Context context, final Handler handler,
+ final OnDrawableLoadedListener listener) {
+ mContext = context;
+ mMessage = Message.obtain(handler, new Runnable() {
+ @Override
+ public void run() {
+ listener.onDrawableLoaded((Drawable) mMessage.obj);
+ }
+ });
+ }
+
+ public LoadDrawableTask(Context context, Message message) {
+ mContext = context;
+ mMessage = message;
+ }
+
+ @Override
+ public void run() {
+ mMessage.obj = loadDrawable(mContext);
+ mMessage.sendToTarget();
+ }
+
+ public void runAsync() {
+ AsyncTask.THREAD_POOL_EXECUTOR.execute(this);
+ }
+ }
+}
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index f67dcb3..efc171c 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -53,8 +53,11 @@ import java.util.Arrays;
* attribute identifier.
* <p>
* A touch feedback drawable may contain multiple child layers, including a
- * special mask layer that is not drawn to the screen. A single layer may be set
- * as the mask by specifying its android:id value as {@link android.R.id#mask}.
+ * special mask layer that is not drawn to the screen. A single layer may be
+ * set as the mask from XML by specifying its {@code android:id} value as
+ * {@link android.R.id#mask}. At run time, a single layer may be set as the
+ * mask using {@code setId(..., android.R.id.mask)} or an existing mask layer
+ * may be replaced using {@code setDrawableByLayerId(android.R.id.mask, ...)}.
* <pre>
* <code>&lt!-- A red ripple masked against an opaque rectangle. --/>
* &ltripple android:color="#ffff0000">
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index b32dcc6..feb8052 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -380,7 +380,7 @@ public final class PdfRenderer implements AutoCloseable {
final long transformPtr = (transform != null) ? transform.native_instance : 0;
- nativeRenderPage(mNativeDocument, mNativePage, destination.getSkBitmap(), contentLeft,
+ nativeRenderPage(mNativeDocument, mNativePage, destination, contentLeft,
contentTop, contentRight, contentBottom, transformPtr, renderMode);
}
@@ -425,7 +425,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, long destPtr,
+ private static native void nativeRenderPage(long documentPtr, long pagePtr, Bitmap dest,
int destLeft, int destTop, int destRight, int destBottom, long matrixPtr, int renderMode);
private static native long nativeOpenPageAndGetSize(long documentPtr, int pageIndex,
Point outSize);