Loading api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -9156,8 +9156,11 @@ package android.graphics { method public void draw(android.graphics.Canvas, android.graphics.RectF); method public void draw(android.graphics.Canvas, android.graphics.Rect); method public void draw(android.graphics.Canvas, android.graphics.Rect, android.graphics.Paint); method public android.graphics.Bitmap getBitmap(); method public int getDensity(); method public int getHeight(); method public java.lang.String getName(); method public android.graphics.Paint getPaint(); method public final android.graphics.Region getTransparentRegion(android.graphics.Rect); method public int getWidth(); method public final boolean hasAlpha(); core/java/android/view/GLES20Canvas.java +3 −3 Original line number Diff line number Diff line Loading @@ -781,7 +781,7 @@ class GLES20Canvas extends HardwareCanvas { int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mChunk, nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } finally { if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); Loading @@ -796,14 +796,14 @@ class GLES20Canvas extends HardwareCanvas { int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mChunk, nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } finally { if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); } } private static native void nDrawPatch(int renderer, int bitmap, byte[] chunks, private static native void nDrawPatch(int renderer, int bitmap, int chunk, float left, float top, float right, float bottom, int paint); @Override Loading core/java/android/view/GLES20DisplayList.java +0 −20 Original line number Diff line number Diff line Loading @@ -16,9 +16,7 @@ package android.view; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.NinePatch; import java.util.ArrayList; Loading @@ -26,12 +24,6 @@ import java.util.ArrayList; * An implementation of display list for OpenGL ES 2.0. */ class GLES20DisplayList extends DisplayList { // These lists ensure that any Bitmaps and DisplayLists recorded by a DisplayList are kept // alive as long as the DisplayList is alive. The Bitmap and DisplayList lists // are populated by the GLES20RecordingCanvas during appropriate drawing calls and are // cleared at the start of a new drawing frame or when the view is detached from the window. private ArrayList<Bitmap> mBitmaps; private ArrayList<NinePatch> mNinePatches; private ArrayList<DisplayList> mChildDisplayLists; private GLES20RecordingCanvas mCanvas; Loading Loading @@ -89,21 +81,9 @@ class GLES20DisplayList extends DisplayList { } void clearReferences() { if (mBitmaps != null) mBitmaps.clear(); if (mNinePatches != null) mNinePatches.clear(); if (mChildDisplayLists != null) mChildDisplayLists.clear(); } ArrayList<Bitmap> getBitmaps() { if (mBitmaps == null) mBitmaps = new ArrayList<Bitmap>(5); return mBitmaps; } ArrayList<NinePatch> getNinePatches() { if (mNinePatches == null) mNinePatches = new ArrayList<NinePatch>(5); return mNinePatches; } ArrayList<DisplayList> getChildDisplayLists() { if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>(); return mChildDisplayLists; Loading core/java/android/view/GLES20RecordingCanvas.java +0 −220 Original line number Diff line number Diff line Loading @@ -16,15 +16,7 @@ package android.view; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Matrix; import android.graphics.NinePatch; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.util.Pools.SynchronizedPool; /** Loading Loading @@ -70,222 +62,10 @@ class GLES20RecordingCanvas extends GLES20Canvas { return getDisplayList(nativeDisplayList); } private void recordShaderBitmap(Paint paint) { if (paint != null) { final Shader shader = paint.getShader(); if (shader instanceof BitmapShader) { mDisplayList.getBitmaps().add(((BitmapShader) shader).mBitmap); } } } @Override public void drawPatch(NinePatch patch, RectF dst, Paint paint) { super.drawPatch(patch, dst, paint); mDisplayList.getBitmaps().add(patch.getBitmap()); mDisplayList.getNinePatches().add(patch); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { super.drawBitmap(bitmap, left, top, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { super.drawBitmap(bitmap, matrix, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { super.drawBitmap(bitmap, src, dst, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { super.drawBitmap(bitmap, src, dst, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, Paint paint) { super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width, int height, boolean hasAlpha, Paint paint) { super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint) { super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawCircle(float cx, float cy, float radius, Paint paint) { super.drawCircle(cx, cy, radius, paint); recordShaderBitmap(paint); } @Override public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) { int status = super.drawDisplayList(displayList, dirty, flags); mDisplayList.getChildDisplayLists().add(displayList); return status; } @Override public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { super.drawLine(startX, startY, stopX, stopY, paint); recordShaderBitmap(paint); } @Override public void drawLines(float[] pts, int offset, int count, Paint paint) { super.drawLines(pts, offset, count, paint); recordShaderBitmap(paint); } @Override public void drawLines(float[] pts, Paint paint) { super.drawLines(pts, paint); recordShaderBitmap(paint); } @Override public void drawOval(RectF oval, Paint paint) { super.drawOval(oval, paint); recordShaderBitmap(paint); } @Override public void drawPaint(Paint paint) { super.drawPaint(paint); recordShaderBitmap(paint); } @Override public void drawPath(Path path, Paint paint) { super.drawPath(path, paint); recordShaderBitmap(paint); } @Override public void drawPoint(float x, float y, Paint paint) { super.drawPoint(x, y, paint); recordShaderBitmap(paint); } @Override public void drawPoints(float[] pts, int offset, int count, Paint paint) { super.drawPoints(pts, offset, count, paint); recordShaderBitmap(paint); } @Override public void drawPoints(float[] pts, Paint paint) { super.drawPoints(pts, paint); recordShaderBitmap(paint); } @Override public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { super.drawPosText(text, index, count, pos, paint); recordShaderBitmap(paint); } @Override public void drawPosText(String text, float[] pos, Paint paint) { super.drawPosText(text, pos, paint); recordShaderBitmap(paint); } @Override public void drawRect(float left, float top, float right, float bottom, Paint paint) { super.drawRect(left, top, right, bottom, paint); recordShaderBitmap(paint); } @Override public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) { super.drawRoundRect(rect, rx, ry, paint); recordShaderBitmap(paint); } @Override public void drawText(char[] text, int index, int count, float x, float y, Paint paint) { super.drawText(text, index, count, x, y, paint); recordShaderBitmap(paint); } @Override public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { super.drawText(text, start, end, x, y, paint); recordShaderBitmap(paint); } @Override public void drawText(String text, int start, int end, float x, float y, Paint paint) { super.drawText(text, start, end, x, y, paint); recordShaderBitmap(paint); } @Override public void drawText(String text, float x, float y, Paint paint) { super.drawText(text, x, y, paint); recordShaderBitmap(paint); } @Override public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) { super.drawTextOnPath(text, index, count, path, hOffset, vOffset, paint); recordShaderBitmap(paint); } @Override public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { super.drawTextOnPath(text, path, hOffset, vOffset, paint); recordShaderBitmap(paint); } @Override public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int dir, Paint paint) { super.drawTextRun(text, index, count, contextIndex, contextCount, x, y, dir, paint); recordShaderBitmap(paint); } @Override public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, int dir, Paint paint) { super.drawTextRun(text, start, end, contextStart, contextEnd, x, y, dir, paint); recordShaderBitmap(paint); } @Override public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, int indexOffset, int indexCount, Paint paint) { super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset, colors, colorOffset, indices, indexOffset, indexCount, paint); recordShaderBitmap(paint); } } core/jni/android/graphics/NinePatch.cpp +89 −99 Original line number Diff line number Diff line Loading @@ -21,22 +21,30 @@ #include <androidfw/ResourceTypes.h> #include <utils/Log.h> #include <Caches.h> #include "SkCanvas.h" #include "SkRegion.h" #include "GraphicsJNI.h" #include "JNIHelp.h" extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds, const SkBitmap& bitmap, const android::Res_png_9patch& chunk, const SkPaint* paint, SkRegion** outRegion); extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds, const SkBitmap& bitmap, const android::Res_png_9patch& chunk, const SkPaint* paint, SkRegion** outRegion); using namespace android; /** * IMPORTANT NOTE: 9patch chunks can be manipuated either as an array of bytes * or as a Res_png_9patch instance. It is important to note that the size of the * array required to hold a 9patch chunk is greater than sizeof(Res_png_9patch). * The code below manipulates chunks as Res_png_9patch* types to draw and as * int8_t* to allocate and free the backing storage. */ class SkNinePatchGlue { public: static jboolean isNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj) { static jboolean isNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj) { if (NULL == obj) { return false; } Loading @@ -45,43 +53,42 @@ public: } const jbyte* array = env->GetByteArrayElements(obj, 0); if (array != NULL) { const Res_png_9patch* chunk = reinterpret_cast<const Res_png_9patch*>(array); const Res_png_9patch* chunk = reinterpret_cast<const Res_png_9patch*>(array); int8_t wasDeserialized = chunk->wasDeserialized; env->ReleaseByteArrayElements(obj, const_cast<jbyte*>(array), JNI_ABORT); env->ReleaseByteArrayElements(obj, const_cast<jbyte*>(array), JNI_ABORT); return wasDeserialized != -1; } return false; } static void validateNinePatchChunk(JNIEnv* env, jobject, jint, jbyteArray obj) { if (env->GetArrayLength(obj) < (int) (sizeof(Res_png_9patch))) { static int8_t* validateNinePatchChunk(JNIEnv* env, jobject, jint, jbyteArray obj) { size_t chunkSize = env->GetArrayLength(obj); if (chunkSize < (int) (sizeof(Res_png_9patch))) { jniThrowRuntimeException(env, "Array too small for chunk."); return; return NULL; } int8_t* storage = new int8_t[chunkSize]; // This call copies the content of the jbyteArray env->GetByteArrayRegion(obj, 0, chunkSize, reinterpret_cast<jbyte*>(storage)); // Deserialize in place, return the array we just allocated return (int8_t*) Res_png_9patch::deserialize(storage); } // XXX Also check that dimensions are correct. static void finalize(JNIEnv* env, jobject, int8_t* patch) { #ifdef USE_OPENGL_RENDERER if (android::uirenderer::Caches::hasInstance()) { Res_png_9patch* p = (Res_png_9patch*) patch; android::uirenderer::Caches::getInstance().resourceCache.destructor(p); return; } #endif // USE_OPENGL_RENDERER delete[] patch; } static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint, jint destDensity, jint srcDensity) { size_t chunkSize = env->GetArrayLength(chunkObj); void* storage = alloca(chunkSize); env->GetByteArrayRegion(chunkObj, 0, chunkSize, reinterpret_cast<jbyte*>(storage)); if (!env->ExceptionCheck()) { // need to deserialize the chunk Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); assert(chunkSize == chunk->serializedSize()); // this relies on deserialization being done in place Res_png_9patch::deserialize(chunk); if (destDensity == srcDensity || destDensity == 0 || srcDensity == 0) { static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) { if (destDensity == srcDensity || destDensity == 0 || srcDensity == 0) { ALOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)", SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop), SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom)); Loading @@ -107,65 +114,50 @@ public: canvas->restore(); } } } static void drawF(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRectF, const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint, jint destDensity, jint srcDensity) { const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) { SkASSERT(canvas); SkASSERT(boundsRectF); SkASSERT(bitmap); SkASSERT(chunkObj); SkASSERT(chunk); // paint is optional SkRect bounds; GraphicsJNI::jrectf_to_rect(env, boundsRectF, &bounds); draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity); draw(env, canvas, bounds, bitmap, chunk, paint, destDensity, srcDensity); } static void drawI(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRect, const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint, jint destDensity, jint srcDensity) { const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) { SkASSERT(canvas); SkASSERT(boundsRect); SkASSERT(bitmap); SkASSERT(chunkObj); SkASSERT(chunk); // paint is optional SkRect bounds; GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds); draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity); draw(env, canvas, bounds, bitmap, chunk, paint, destDensity, srcDensity); } static jint getTransparentRegion(JNIEnv* env, jobject, const SkBitmap* bitmap, jbyteArray chunkObj, jobject boundsRect) { static jint getTransparentRegion(JNIEnv* env, jobject, const SkBitmap* bitmap, Res_png_9patch* chunk, jobject boundsRect) { SkASSERT(bitmap); SkASSERT(chunkObj); SkASSERT(chunk); SkASSERT(boundsRect); SkRect bounds; GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds); size_t chunkSize = env->GetArrayLength(chunkObj); void* storage = alloca(chunkSize); env->GetByteArrayRegion(chunkObj, 0, chunkSize, reinterpret_cast<jbyte*>(storage)); if (!env->ExceptionCheck()) { // need to deserialize the chunk Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); assert(chunkSize == chunk->serializedSize()); // this relies on deserialization being done in place Res_png_9patch::deserialize(chunk); SkRegion* region = NULL; NinePatch_Draw(NULL, bounds, *bitmap, *chunk, NULL, ®ion); return (jint) region; } return 0; } }; Loading @@ -175,17 +167,15 @@ public: static JNINativeMethod gNinePatchMethods[] = { { "isNinePatchChunk", "([B)Z", (void*) SkNinePatchGlue::isNinePatchChunk }, { "validateNinePatchChunk", "(I[B)V", (void*)SkNinePatchGlue::validateNinePatchChunk }, { "nativeDraw", "(ILandroid/graphics/RectF;I[BIII)V", (void*)SkNinePatchGlue::drawF }, { "nativeDraw", "(ILandroid/graphics/Rect;I[BIII)V", (void*)SkNinePatchGlue::drawI }, { "nativeGetTransparentRegion", "(I[BLandroid/graphics/Rect;)I", { "validateNinePatchChunk", "(I[B)I", (void*) SkNinePatchGlue::validateNinePatchChunk }, { "nativeFinalize", "(I)V", (void*) SkNinePatchGlue::finalize }, { "nativeDraw", "(ILandroid/graphics/RectF;IIIII)V", (void*) SkNinePatchGlue::drawF }, { "nativeDraw", "(ILandroid/graphics/Rect;IIIII)V", (void*) SkNinePatchGlue::drawI }, { "nativeGetTransparentRegion", "(IILandroid/graphics/Rect;)I", (void*) SkNinePatchGlue::getTransparentRegion } }; int register_android_graphics_NinePatch(JNIEnv* env) { int register_android_graphics_NinePatch(JNIEnv* env) { return android::AndroidRuntime::registerNativeMethods(env, "android/graphics/NinePatch", gNinePatchMethods, SK_ARRAY_COUNT(gNinePatchMethods)); "android/graphics/NinePatch", gNinePatchMethods, SK_ARRAY_COUNT(gNinePatchMethods)); } Loading
api/current.txt +3 −0 Original line number Diff line number Diff line Loading @@ -9156,8 +9156,11 @@ package android.graphics { method public void draw(android.graphics.Canvas, android.graphics.RectF); method public void draw(android.graphics.Canvas, android.graphics.Rect); method public void draw(android.graphics.Canvas, android.graphics.Rect, android.graphics.Paint); method public android.graphics.Bitmap getBitmap(); method public int getDensity(); method public int getHeight(); method public java.lang.String getName(); method public android.graphics.Paint getPaint(); method public final android.graphics.Region getTransparentRegion(android.graphics.Rect); method public int getWidth(); method public final boolean hasAlpha();
core/java/android/view/GLES20Canvas.java +3 −3 Original line number Diff line number Diff line Loading @@ -781,7 +781,7 @@ class GLES20Canvas extends HardwareCanvas { int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mChunk, nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } finally { if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); Loading @@ -796,14 +796,14 @@ class GLES20Canvas extends HardwareCanvas { int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE; try { final int nativePaint = paint == null ? 0 : paint.mNativePaint; nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mChunk, nDrawPatch(mRenderer, bitmap.mNativeBitmap, patch.mNativeChunk, dst.left, dst.top, dst.right, dst.bottom, nativePaint); } finally { if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier); } } private static native void nDrawPatch(int renderer, int bitmap, byte[] chunks, private static native void nDrawPatch(int renderer, int bitmap, int chunk, float left, float top, float right, float bottom, int paint); @Override Loading
core/java/android/view/GLES20DisplayList.java +0 −20 Original line number Diff line number Diff line Loading @@ -16,9 +16,7 @@ package android.view; import android.graphics.Bitmap; import android.graphics.Matrix; import android.graphics.NinePatch; import java.util.ArrayList; Loading @@ -26,12 +24,6 @@ import java.util.ArrayList; * An implementation of display list for OpenGL ES 2.0. */ class GLES20DisplayList extends DisplayList { // These lists ensure that any Bitmaps and DisplayLists recorded by a DisplayList are kept // alive as long as the DisplayList is alive. The Bitmap and DisplayList lists // are populated by the GLES20RecordingCanvas during appropriate drawing calls and are // cleared at the start of a new drawing frame or when the view is detached from the window. private ArrayList<Bitmap> mBitmaps; private ArrayList<NinePatch> mNinePatches; private ArrayList<DisplayList> mChildDisplayLists; private GLES20RecordingCanvas mCanvas; Loading Loading @@ -89,21 +81,9 @@ class GLES20DisplayList extends DisplayList { } void clearReferences() { if (mBitmaps != null) mBitmaps.clear(); if (mNinePatches != null) mNinePatches.clear(); if (mChildDisplayLists != null) mChildDisplayLists.clear(); } ArrayList<Bitmap> getBitmaps() { if (mBitmaps == null) mBitmaps = new ArrayList<Bitmap>(5); return mBitmaps; } ArrayList<NinePatch> getNinePatches() { if (mNinePatches == null) mNinePatches = new ArrayList<NinePatch>(5); return mNinePatches; } ArrayList<DisplayList> getChildDisplayLists() { if (mChildDisplayLists == null) mChildDisplayLists = new ArrayList<DisplayList>(); return mChildDisplayLists; Loading
core/java/android/view/GLES20RecordingCanvas.java +0 −220 Original line number Diff line number Diff line Loading @@ -16,15 +16,7 @@ package android.view; import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Matrix; import android.graphics.NinePatch; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.Shader; import android.util.Pools.SynchronizedPool; /** Loading Loading @@ -70,222 +62,10 @@ class GLES20RecordingCanvas extends GLES20Canvas { return getDisplayList(nativeDisplayList); } private void recordShaderBitmap(Paint paint) { if (paint != null) { final Shader shader = paint.getShader(); if (shader instanceof BitmapShader) { mDisplayList.getBitmaps().add(((BitmapShader) shader).mBitmap); } } } @Override public void drawPatch(NinePatch patch, RectF dst, Paint paint) { super.drawPatch(patch, dst, paint); mDisplayList.getBitmaps().add(patch.getBitmap()); mDisplayList.getNinePatches().add(patch); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { super.drawBitmap(bitmap, left, top, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { super.drawBitmap(bitmap, matrix, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { super.drawBitmap(bitmap, src, dst, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { super.drawBitmap(bitmap, src, dst, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(int[] colors, int offset, int stride, float x, float y, int width, int height, boolean hasAlpha, Paint paint) { super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width, int height, boolean hasAlpha, Paint paint) { super.drawBitmap(colors, offset, stride, x, y, width, height, hasAlpha, paint); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint) { super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, paint); mDisplayList.getBitmaps().add(bitmap); // Shaders in the Paint are ignored when drawing a Bitmap } @Override public void drawCircle(float cx, float cy, float radius, Paint paint) { super.drawCircle(cx, cy, radius, paint); recordShaderBitmap(paint); } @Override public int drawDisplayList(DisplayList displayList, Rect dirty, int flags) { int status = super.drawDisplayList(displayList, dirty, flags); mDisplayList.getChildDisplayLists().add(displayList); return status; } @Override public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { super.drawLine(startX, startY, stopX, stopY, paint); recordShaderBitmap(paint); } @Override public void drawLines(float[] pts, int offset, int count, Paint paint) { super.drawLines(pts, offset, count, paint); recordShaderBitmap(paint); } @Override public void drawLines(float[] pts, Paint paint) { super.drawLines(pts, paint); recordShaderBitmap(paint); } @Override public void drawOval(RectF oval, Paint paint) { super.drawOval(oval, paint); recordShaderBitmap(paint); } @Override public void drawPaint(Paint paint) { super.drawPaint(paint); recordShaderBitmap(paint); } @Override public void drawPath(Path path, Paint paint) { super.drawPath(path, paint); recordShaderBitmap(paint); } @Override public void drawPoint(float x, float y, Paint paint) { super.drawPoint(x, y, paint); recordShaderBitmap(paint); } @Override public void drawPoints(float[] pts, int offset, int count, Paint paint) { super.drawPoints(pts, offset, count, paint); recordShaderBitmap(paint); } @Override public void drawPoints(float[] pts, Paint paint) { super.drawPoints(pts, paint); recordShaderBitmap(paint); } @Override public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { super.drawPosText(text, index, count, pos, paint); recordShaderBitmap(paint); } @Override public void drawPosText(String text, float[] pos, Paint paint) { super.drawPosText(text, pos, paint); recordShaderBitmap(paint); } @Override public void drawRect(float left, float top, float right, float bottom, Paint paint) { super.drawRect(left, top, right, bottom, paint); recordShaderBitmap(paint); } @Override public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) { super.drawRoundRect(rect, rx, ry, paint); recordShaderBitmap(paint); } @Override public void drawText(char[] text, int index, int count, float x, float y, Paint paint) { super.drawText(text, index, count, x, y, paint); recordShaderBitmap(paint); } @Override public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { super.drawText(text, start, end, x, y, paint); recordShaderBitmap(paint); } @Override public void drawText(String text, int start, int end, float x, float y, Paint paint) { super.drawText(text, start, end, x, y, paint); recordShaderBitmap(paint); } @Override public void drawText(String text, float x, float y, Paint paint) { super.drawText(text, x, y, paint); recordShaderBitmap(paint); } @Override public void drawTextOnPath(char[] text, int index, int count, Path path, float hOffset, float vOffset, Paint paint) { super.drawTextOnPath(text, index, count, path, hOffset, vOffset, paint); recordShaderBitmap(paint); } @Override public void drawTextOnPath(String text, Path path, float hOffset, float vOffset, Paint paint) { super.drawTextOnPath(text, path, hOffset, vOffset, paint); recordShaderBitmap(paint); } @Override public void drawTextRun(char[] text, int index, int count, int contextIndex, int contextCount, float x, float y, int dir, Paint paint) { super.drawTextRun(text, index, count, contextIndex, contextCount, x, y, dir, paint); recordShaderBitmap(paint); } @Override public void drawTextRun(CharSequence text, int start, int end, int contextStart, int contextEnd, float x, float y, int dir, Paint paint) { super.drawTextRun(text, start, end, contextStart, contextEnd, x, y, dir, paint); recordShaderBitmap(paint); } @Override public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, int indexOffset, int indexCount, Paint paint) { super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset, colors, colorOffset, indices, indexOffset, indexCount, paint); recordShaderBitmap(paint); } }
core/jni/android/graphics/NinePatch.cpp +89 −99 Original line number Diff line number Diff line Loading @@ -21,22 +21,30 @@ #include <androidfw/ResourceTypes.h> #include <utils/Log.h> #include <Caches.h> #include "SkCanvas.h" #include "SkRegion.h" #include "GraphicsJNI.h" #include "JNIHelp.h" extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds, const SkBitmap& bitmap, const android::Res_png_9patch& chunk, const SkPaint* paint, SkRegion** outRegion); extern void NinePatch_Draw(SkCanvas* canvas, const SkRect& bounds, const SkBitmap& bitmap, const android::Res_png_9patch& chunk, const SkPaint* paint, SkRegion** outRegion); using namespace android; /** * IMPORTANT NOTE: 9patch chunks can be manipuated either as an array of bytes * or as a Res_png_9patch instance. It is important to note that the size of the * array required to hold a 9patch chunk is greater than sizeof(Res_png_9patch). * The code below manipulates chunks as Res_png_9patch* types to draw and as * int8_t* to allocate and free the backing storage. */ class SkNinePatchGlue { public: static jboolean isNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj) { static jboolean isNinePatchChunk(JNIEnv* env, jobject, jbyteArray obj) { if (NULL == obj) { return false; } Loading @@ -45,43 +53,42 @@ public: } const jbyte* array = env->GetByteArrayElements(obj, 0); if (array != NULL) { const Res_png_9patch* chunk = reinterpret_cast<const Res_png_9patch*>(array); const Res_png_9patch* chunk = reinterpret_cast<const Res_png_9patch*>(array); int8_t wasDeserialized = chunk->wasDeserialized; env->ReleaseByteArrayElements(obj, const_cast<jbyte*>(array), JNI_ABORT); env->ReleaseByteArrayElements(obj, const_cast<jbyte*>(array), JNI_ABORT); return wasDeserialized != -1; } return false; } static void validateNinePatchChunk(JNIEnv* env, jobject, jint, jbyteArray obj) { if (env->GetArrayLength(obj) < (int) (sizeof(Res_png_9patch))) { static int8_t* validateNinePatchChunk(JNIEnv* env, jobject, jint, jbyteArray obj) { size_t chunkSize = env->GetArrayLength(obj); if (chunkSize < (int) (sizeof(Res_png_9patch))) { jniThrowRuntimeException(env, "Array too small for chunk."); return; return NULL; } int8_t* storage = new int8_t[chunkSize]; // This call copies the content of the jbyteArray env->GetByteArrayRegion(obj, 0, chunkSize, reinterpret_cast<jbyte*>(storage)); // Deserialize in place, return the array we just allocated return (int8_t*) Res_png_9patch::deserialize(storage); } // XXX Also check that dimensions are correct. static void finalize(JNIEnv* env, jobject, int8_t* patch) { #ifdef USE_OPENGL_RENDERER if (android::uirenderer::Caches::hasInstance()) { Res_png_9patch* p = (Res_png_9patch*) patch; android::uirenderer::Caches::getInstance().resourceCache.destructor(p); return; } #endif // USE_OPENGL_RENDERER delete[] patch; } static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint, jint destDensity, jint srcDensity) { size_t chunkSize = env->GetArrayLength(chunkObj); void* storage = alloca(chunkSize); env->GetByteArrayRegion(chunkObj, 0, chunkSize, reinterpret_cast<jbyte*>(storage)); if (!env->ExceptionCheck()) { // need to deserialize the chunk Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); assert(chunkSize == chunk->serializedSize()); // this relies on deserialization being done in place Res_png_9patch::deserialize(chunk); if (destDensity == srcDensity || destDensity == 0 || srcDensity == 0) { static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) { if (destDensity == srcDensity || destDensity == 0 || srcDensity == 0) { ALOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)", SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop), SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom)); Loading @@ -107,65 +114,50 @@ public: canvas->restore(); } } } static void drawF(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRectF, const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint, jint destDensity, jint srcDensity) { const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) { SkASSERT(canvas); SkASSERT(boundsRectF); SkASSERT(bitmap); SkASSERT(chunkObj); SkASSERT(chunk); // paint is optional SkRect bounds; GraphicsJNI::jrectf_to_rect(env, boundsRectF, &bounds); draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity); draw(env, canvas, bounds, bitmap, chunk, paint, destDensity, srcDensity); } static void drawI(JNIEnv* env, jobject, SkCanvas* canvas, jobject boundsRect, const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint, jint destDensity, jint srcDensity) { const SkBitmap* bitmap, Res_png_9patch* chunk, const SkPaint* paint, jint destDensity, jint srcDensity) { SkASSERT(canvas); SkASSERT(boundsRect); SkASSERT(bitmap); SkASSERT(chunkObj); SkASSERT(chunk); // paint is optional SkRect bounds; GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds); draw(env, canvas, bounds, bitmap, chunkObj, paint, destDensity, srcDensity); draw(env, canvas, bounds, bitmap, chunk, paint, destDensity, srcDensity); } static jint getTransparentRegion(JNIEnv* env, jobject, const SkBitmap* bitmap, jbyteArray chunkObj, jobject boundsRect) { static jint getTransparentRegion(JNIEnv* env, jobject, const SkBitmap* bitmap, Res_png_9patch* chunk, jobject boundsRect) { SkASSERT(bitmap); SkASSERT(chunkObj); SkASSERT(chunk); SkASSERT(boundsRect); SkRect bounds; GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds); size_t chunkSize = env->GetArrayLength(chunkObj); void* storage = alloca(chunkSize); env->GetByteArrayRegion(chunkObj, 0, chunkSize, reinterpret_cast<jbyte*>(storage)); if (!env->ExceptionCheck()) { // need to deserialize the chunk Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); assert(chunkSize == chunk->serializedSize()); // this relies on deserialization being done in place Res_png_9patch::deserialize(chunk); SkRegion* region = NULL; NinePatch_Draw(NULL, bounds, *bitmap, *chunk, NULL, ®ion); return (jint) region; } return 0; } }; Loading @@ -175,17 +167,15 @@ public: static JNINativeMethod gNinePatchMethods[] = { { "isNinePatchChunk", "([B)Z", (void*) SkNinePatchGlue::isNinePatchChunk }, { "validateNinePatchChunk", "(I[B)V", (void*)SkNinePatchGlue::validateNinePatchChunk }, { "nativeDraw", "(ILandroid/graphics/RectF;I[BIII)V", (void*)SkNinePatchGlue::drawF }, { "nativeDraw", "(ILandroid/graphics/Rect;I[BIII)V", (void*)SkNinePatchGlue::drawI }, { "nativeGetTransparentRegion", "(I[BLandroid/graphics/Rect;)I", { "validateNinePatchChunk", "(I[B)I", (void*) SkNinePatchGlue::validateNinePatchChunk }, { "nativeFinalize", "(I)V", (void*) SkNinePatchGlue::finalize }, { "nativeDraw", "(ILandroid/graphics/RectF;IIIII)V", (void*) SkNinePatchGlue::drawF }, { "nativeDraw", "(ILandroid/graphics/Rect;IIIII)V", (void*) SkNinePatchGlue::drawI }, { "nativeGetTransparentRegion", "(IILandroid/graphics/Rect;)I", (void*) SkNinePatchGlue::getTransparentRegion } }; int register_android_graphics_NinePatch(JNIEnv* env) { int register_android_graphics_NinePatch(JNIEnv* env) { return android::AndroidRuntime::registerNativeMethods(env, "android/graphics/NinePatch", gNinePatchMethods, SK_ARRAY_COUNT(gNinePatchMethods)); "android/graphics/NinePatch", gNinePatchMethods, SK_ARRAY_COUNT(gNinePatchMethods)); }