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); }
// found and fixed for webkit: mishandling when we hit recursion limit on // mostly degenerate cubic flatness test static void regression_cubic(skiatest::Reporter* reporter) { SkPath path, stroke; SkPaint paint; path.moveTo(SkFloatToFixed(460.2881309415525f), SkFloatToFixed(303.250847066498)); path.cubicTo(SkFloatToFixed(463.36378422175284), SkFloatToFixed(302.1169735073363), SkFloatToFixed(456.32239330810046), SkFloatToFixed(304.720354932878), SkFloatToFixed(453.15255460013304), SkFloatToFixed(305.788586869862)); SkRect fillR, strokeR; fillR = path.getBounds(); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(SkIntToScalar(2)); paint.getFillPath(path, &stroke); strokeR = stroke.getBounds(); SkRect maxR = fillR; SkScalar miter = SkMaxScalar(SK_Scalar1, paint.getStrokeMiter()); SkScalar inset = paint.getStrokeJoin() == SkPaint::kMiter_Join ? SkScalarMul(paint.getStrokeWidth(), miter) : paint.getStrokeWidth(); maxR.inset(-inset, -inset); // test that our stroke didn't explode REPORTER_ASSERT(reporter, maxR.contains(strokeR)); }
SkFixed TwoPtRadial::nextT() { float roots[2]; float C = sqr(fRelX) + sqr(fRelY) - fRadius2; int countRoots = find_quad_roots(fA, fB, C, roots); fRelX += fIncX; fRelY += fIncY; fB += fDB; if (0 == countRoots) { return kDontDrawT; } // Prefer the bigger t value if both give a radius(t) > 0 // find_quad_roots returns the values sorted, so we start with the last float t = roots[countRoots - 1]; float r = lerp(fRadius, fDRadius, t); if (r <= 0) { t = roots[0]; // might be the same as roots[countRoots-1] r = lerp(fRadius, fDRadius, t); if (r <= 0) { return kDontDrawT; } } return SkFloatToFixed(t); }
static void DrawRoundRect() { #ifdef SK_SCALAR_IS_FIXED bool ret = false; SkPaint paint; SkBitmap bitmap; SkCanvas canvas; SkMatrix matrix; matrix.reset(); bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1370, 812); bitmap.allocPixels(); canvas.setBitmapDevice(bitmap); // set up clipper SkRect skclip; skclip.set(SkIntToFixed(284), SkIntToFixed(40), SkIntToFixed(1370), SkIntToFixed(708)); ret = canvas.clipRect(skclip); SkASSERT(ret); matrix.set(SkMatrix::kMTransX, SkFloatToFixed(-1153.28)); matrix.set(SkMatrix::kMTransY, SkFloatToFixed(1180.50)); matrix.set(SkMatrix::kMScaleX, SkFloatToFixed(0.177171)); matrix.set(SkMatrix::kMScaleY, SkFloatToFixed(0.177043)); matrix.set(SkMatrix::kMSkewX, SkFloatToFixed(0.126968)); matrix.set(SkMatrix::kMSkewY, SkFloatToFixed(-0.126876)); matrix.set(SkMatrix::kMPersp0, SkFloatToFixed(0.0)); matrix.set(SkMatrix::kMPersp1, SkFloatToFixed(0.0)); ret = canvas.concat(matrix); paint.setAntiAlias(true); paint.setColor(0xb2202020); paint.setStyle(SkPaint::kStroke_Style); paint.setStrokeWidth(SkFloatToFixed(68.13)); SkRect r; r.set(SkFloatToFixed(-313.714417), SkFloatToFixed(-4.826389), SkFloatToFixed(18014.447266), SkFloatToFixed(1858.154541)); canvas.drawRoundRect(r, SkFloatToFixed(91.756363), SkFloatToFixed(91.756363), paint); #endif }
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); }