static void drawVertices(JNIEnv* env, jobject, jlong canvasHandle, jint modeHandle, jint vertexCount, jfloatArray jverts, jint vertIndex, jfloatArray jtexs, jint texIndex, jintArray jcolors, jint colorIndex, jshortArray jindices, jint indexIndex, jint indexCount, jlong paintHandle) { AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount); AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount); AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount); AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount); const float* verts = vertA.ptr() + vertIndex; const float* texs = texA.ptr() + vertIndex; const int* colors = NULL; const uint16_t* indices = NULL; if (jcolors != NULL) { colors = colorA.ptr() + colorIndex; } if (jindices != NULL) { indices = (const uint16_t*)(indexA.ptr() + indexIndex); } SkCanvas::VertexMode mode = static_cast<SkCanvas::VertexMode>(modeHandle); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); get_canvas(canvasHandle)->drawVertices(mode, vertexCount, verts, texs, colors, indices, indexCount, *paint); }
static void drawVertices(JNIEnv* env, jobject, SkCanvas* canvas, SkCanvas::VertexMode mode, int vertexCount, jfloatArray jverts, int vertIndex, jfloatArray jtexs, int texIndex, jintArray jcolors, int colorIndex, jshortArray jindices, int indexIndex, int indexCount, const SkPaint* paint) { AutoJavaFloatArray vertA(env, jverts, vertIndex + vertexCount); AutoJavaFloatArray texA(env, jtexs, texIndex + vertexCount); AutoJavaIntArray colorA(env, jcolors, colorIndex + vertexCount); AutoJavaShortArray indexA(env, jindices, indexIndex + indexCount); const int ptCount = vertexCount >> 1; SkPoint* verts; SkPoint* texs = NULL; #ifdef SK_SCALAR_IS_FLOAT verts = (SkPoint*)(vertA.ptr() + vertIndex); if (jtexs != NULL) { texs = (SkPoint*)(texA.ptr() + texIndex); } #else int count = ptCount; // for verts if (jtexs != NULL) { count += ptCount; // += for texs } SkAutoMalloc storage(count * sizeof(SkPoint)); verts = (SkPoint*)storage.get(); const float* src = vertA.ptr() + vertIndex; for (int i = 0; i < ptCount; i++) { verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); src += 2; } if (jtexs != NULL) { texs = verts + ptCount; src = texA.ptr() + texIndex; for (int i = 0; i < ptCount; i++) { texs[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); src += 2; } } #endif const SkColor* colors = NULL; const uint16_t* indices = NULL; if (jcolors != NULL) { colors = (const SkColor*)(colorA.ptr() + colorIndex); } if (jindices != NULL) { indices = (const uint16_t*)(indexA.ptr() + indexIndex); } canvas->drawVertices(mode, ptCount, verts, texs, colors, NULL, indices, indexCount, *paint); }
static void drawBitmapMesh(JNIEnv* env, jobject, jlong canvasHandle, jlong bitmapHandle, jint meshWidth, jint meshHeight, jfloatArray jverts, jint vertIndex, jintArray jcolors, jint colorIndex, jlong paintHandle) { const int ptCount = (meshWidth + 1) * (meshHeight + 1); AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1)); AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount); const SkBitmap* bitmap = reinterpret_cast<SkBitmap*>(bitmapHandle); const Paint* paint = reinterpret_cast<Paint*>(paintHandle); get_canvas(canvasHandle)->drawBitmapMesh(*bitmap, meshWidth, meshHeight, vertA.ptr(), colorA.ptr(), paint); }
static void drawBitmapMesh(JNIEnv* env, jobject, SkCanvas* canvas, const SkBitmap* bitmap, int meshWidth, int meshHeight, jfloatArray jverts, int vertIndex, jintArray jcolors, int colorIndex, const SkPaint* paint) { const int ptCount = (meshWidth + 1) * (meshHeight + 1); const int indexCount = meshWidth * meshHeight * 6; AutoJavaFloatArray vertA(env, jverts, vertIndex + (ptCount << 1)); AutoJavaIntArray colorA(env, jcolors, colorIndex + ptCount); /* Our temp storage holds 2 or 3 arrays. texture points [ptCount * sizeof(SkPoint)] optionally vertex points [ptCount * sizeof(SkPoint)] if we need a copy to convert from float to fixed indices [ptCount * sizeof(uint16_t)] */ ssize_t storageSize = ptCount * sizeof(SkPoint); // texs[] #ifdef SK_SCALAR_IS_FIXED storageSize += ptCount * sizeof(SkPoint); // storage for verts #endif storageSize += indexCount * sizeof(uint16_t); // indices[] SkAutoMalloc storage(storageSize); SkPoint* texs = (SkPoint*)storage.get(); SkPoint* verts; uint16_t* indices; #ifdef SK_SCALAR_IS_FLOAT verts = (SkPoint*)(vertA.ptr() + vertIndex); indices = (uint16_t*)(texs + ptCount); #else verts = texs + ptCount; indices = (uint16_t*)(verts + ptCount); // convert floats to fixed { const float* src = vertA.ptr() + vertIndex; for (int i = 0; i < ptCount; i++) { verts[i].set(SkFloatToFixed(src[0]), SkFloatToFixed(src[1])); src += 2; } } #endif // cons up texture coordinates and indices { const SkScalar w = SkIntToScalar(bitmap->width()); const SkScalar h = SkIntToScalar(bitmap->height()); const SkScalar dx = w / meshWidth; const SkScalar dy = h / meshHeight; SkPoint* texsPtr = texs; SkScalar y = 0; for (int i = 0; i <= meshHeight; i++) { if (i == meshHeight) { y = h; // to ensure numerically we hit h exactly } SkScalar x = 0; for (int j = 0; j < meshWidth; j++) { texsPtr->set(x, y); texsPtr += 1; x += dx; } texsPtr->set(w, y); texsPtr += 1; y += dy; } SkASSERT(texsPtr - texs == ptCount); } // cons up indices { uint16_t* indexPtr = indices; int index = 0; for (int i = 0; i < meshHeight; i++) { for (int j = 0; j < meshWidth; j++) { // lower-left triangle *indexPtr++ = index; *indexPtr++ = index + meshWidth + 1; *indexPtr++ = index + meshWidth + 2; // upper-right triangle *indexPtr++ = index; *indexPtr++ = index + meshWidth + 2; *indexPtr++ = index + 1; // bump to the next cell index += 1; } // bump to the next row index += 1; } SkASSERT(indexPtr - indices == indexCount); SkASSERT((char*)indexPtr - (char*)storage.get() == storageSize); } // double-check that we have legal indices #ifdef SK_DEBUG { for (int i = 0; i < indexCount; i++) { SkASSERT((unsigned)indices[i] < (unsigned)ptCount); } } #endif // cons-up a shader for the bitmap SkPaint tmpPaint; if (paint) { tmpPaint = *paint; } SkShader* shader = SkShader::CreateBitmapShader(*bitmap, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); tmpPaint.setShader(shader)->safeUnref(); canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts, texs, (const SkColor*)colorA.ptr(), NULL, indices, indexCount, tmpPaint); }