static jint getTransparentRegion(JNIEnv* env, jobject, const SkBitmap* bitmap, jbyteArray chunkObj, jobject boundsRect) { SkASSERT(bitmap); SkASSERT(chunkObj); 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; }
void NinePatchGlue::draw(SkCanvas& canvas, SkRect& bounds, const BitmapGlue& bitmap, const NativeArray<uint8_t>& chunkArray, const PaintGlue* paint, int dest_density, int src_density) { void* storage = alloca(chunkArray.length()); memcpy(storage, chunkArray.ptr(0, chunkArray.length()), chunkArray.length()); // need to deserialize the chunk Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); SkASSERT(chunkArray.length() == chunk->serializedSize()); // this relies on deserialization being done in place Res_png_9patch::deserialize(chunk); if (dest_density == src_density || dest_density == 0 || src_density == 0) { NinePatch_Draw(&canvas, bounds, bitmap, *chunk, paint, NULL); } else { canvas.save(); float scale = dest_density / (float)src_density; canvas.translate(bounds.fLeft, bounds.fTop); canvas.scale(scale, scale); bounds.fRight = bounds.fRight-bounds.fLeft/ scale; bounds.fBottom = bounds.fBottom-bounds.fTop / scale; bounds.fLeft = bounds.fTop = 0; NinePatch_Draw(&canvas, bounds, bitmap, *chunk, paint, NULL); canvas.restore(); } }
static jint getTransparentRegion(JNIEnv* env, jobject, const SkBitmap* bitmap, jbyteArray chunkObj, jobject boundsRect) { SkASSERT(bitmap); SkASSERT(chunkObj); SkASSERT(boundsRect); SkRect bounds; GraphicsJNI::jrect_to_rect(env, boundsRect, &bounds); const jbyte* array = (jbyte*)env->GetByteArrayElements(chunkObj, 0); if (array != NULL) { size_t chunkSize = env->GetArrayLength(chunkObj); // need to deserialize the chunk void* storage = alloca(chunkSize); Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); memcpy(chunk, array, chunkSize); 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); env->ReleaseByteArrayElements(chunkObj, const_cast<jbyte*>(array), JNI_ABORT); return (jint)region; } return 0; }
bool NinePatchPeeker::peek(const char tag[], const void* data, size_t length) { if (strcmp("npTc", tag) == 0 && length >= sizeof(Res_png_9patch)) { Res_png_9patch* patch = (Res_png_9patch*) data; size_t patchSize = patch->serializedSize(); assert(length == patchSize); // You have to copy the data because it is owned by the png reader Res_png_9patch* patchNew = (Res_png_9patch*) malloc(patchSize); memcpy(patchNew, patch, patchSize); Res_png_9patch::deserialize(patchNew); patchNew->fileToDevice(); free(fPatch); fPatch = patchNew; fPatchSize = patchSize; //printf("9patch: (%d,%d)-(%d,%d)\n", // fPatch.sizeLeft, fPatch.sizeTop, // fPatch.sizeRight, fPatch.sizeBottom); // now update our host to force index or 32bit config // 'cause we don't want 565 predithered, since as a 9patch, we know // we will be stretched, and therefore we want to dither afterwards. SkImageDecoder::PrefConfigTable table; table.fPrefFor_8Index_NoAlpha_src = SkBitmap::kIndex8_Config; table.fPrefFor_8Index_YesAlpha_src = SkBitmap::kIndex8_Config; table.fPrefFor_8Gray_src = SkBitmap::kARGB_8888_Config; table.fPrefFor_8bpc_NoAlpha_src = SkBitmap::kARGB_8888_Config; table.fPrefFor_8bpc_YesAlpha_src = SkBitmap::kARGB_8888_Config; fHost->setPrefConfigTable(table); } else if (strcmp("npLb", tag) == 0 && length == sizeof(int) * 4) { fLayoutBounds = new int[4]; memcpy(fLayoutBounds, data, sizeof(int) * 4); } return true; // keep on decoding }
static void draw(JNIEnv* env, SkCanvas* canvas, SkRect& bounds, const SkBitmap* bitmap, jbyteArray chunkObj, const SkPaint* paint) { const jbyte* array = env->GetByteArrayElements(chunkObj, 0); if (array != NULL) { size_t chunkSize = env->GetArrayLength(chunkObj); // need to deserialize the chunk void* storage = alloca(chunkSize); Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); memcpy(chunk, array, chunkSize); assert(chunkSize == chunk->serializedSize()); // this relies on deserialization being done in place Res_png_9patch::deserialize(chunk); NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL); env->ReleaseByteArrayElements(chunkObj, const_cast<jbyte*>(array), JNI_ABORT); } }
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) { LOGV("Drawing unscaled 9-patch: (%g,%g)-(%g,%g)", SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop), SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom)); NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL); } else { canvas->save(); SkScalar scale = SkFloatToScalar(destDensity / (float)srcDensity); canvas->translate(bounds.fLeft, bounds.fTop); canvas->scale(scale, scale); bounds.fRight = SkScalarDiv(bounds.fRight-bounds.fLeft, scale); bounds.fBottom = SkScalarDiv(bounds.fBottom-bounds.fTop, scale); bounds.fLeft = bounds.fTop = 0; LOGV("Drawing scaled 9-patch: (%g,%g)-(%g,%g) srcDensity=%d destDensity=%d", SkScalarToFloat(bounds.fLeft), SkScalarToFloat(bounds.fTop), SkScalarToFloat(bounds.fRight), SkScalarToFloat(bounds.fBottom), srcDensity, destDensity); NinePatch_Draw(canvas, bounds, *bitmap, *chunk, paint, NULL); canvas->restore(); } } }
RegionGlue* NinePatchGlue::getTransparentRegion(const BitmapGlue& bitmap, const NativeArray<uint8_t>& chunkArray, const SkIRect& ibounds) { SkRect bounds; bounds.set(ibounds); void* storage = alloca(chunkArray.length()); memcpy(storage, chunkArray.ptr(0, chunkArray.length()), chunkArray.length()); // need to deserialize the chunk Res_png_9patch* chunk = static_cast<Res_png_9patch*>(storage); SkASSERT(chunkArray.length() == chunk->serializedSize()); // this relies on deserialization being done in place Res_png_9patch::deserialize(chunk); RegionGlue* region = NULL; NinePatch_Draw(NULL, bounds, bitmap, *chunk, NULL, ®ion); return region; };
virtual bool peek(const char tag[], const void* data, size_t length) { if (strcmp("npTc", tag) == 0 && length >= sizeof(Res_png_9patch)) { Res_png_9patch* patch = (Res_png_9patch*) data; size_t patchSize = patch->serializedSize(); assert(length == patchSize); // You have to copy the data because it is owned by the png reader Res_png_9patch* patchNew = (Res_png_9patch*) malloc(patchSize); memcpy(patchNew, patch, patchSize); // this relies on deserialization being done in place Res_png_9patch::deserialize(patchNew); patchNew->fileToDevice(); if (fPatchIsValid) { free(fPatch); } fPatch = patchNew; //printf("9patch: (%d,%d)-(%d,%d)\n", // fPatch.sizeLeft, fPatch.sizeTop, // fPatch.sizeRight, fPatch.sizeBottom); fPatchIsValid = true; // now update our host to force index or 32bit config // 'cause we don't want 565 predithered, since as a 9patch, we know // we will be stretched, and therefore we want to dither afterwards. static const SkBitmap::Config gNo565Pref[] = { SkBitmap::kIndex8_Config, SkBitmap::kIndex8_Config, SkBitmap::kARGB_8888_Config, SkBitmap::kARGB_8888_Config, SkBitmap::kARGB_8888_Config, SkBitmap::kARGB_8888_Config, }; fHost->setPrefConfigTable(gNo565Pref); } else { fPatch = NULL; } return true; // keep on decoding }