static void containsText_proc(int loops, const SkPaint& paint, const void* text, size_t len, int glyphCount) { for (int i = 0; i < loops; ++i) { paint.containsText(text, len); } }
virtual void onDraw(SkCanvas* canvas) { struct FillAndName { SkPath::FillType fFill; const char* fName; }; static const FillAndName gFills[] = { {SkPath::kWinding_FillType, "Winding"}, {SkPath::kEvenOdd_FillType, "Even / Odd"}, {SkPath::kInverseWinding_FillType, "Inverse Winding"}, {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"}, }; struct StyleAndName { SkPaint::Style fStyle; const char* fName; }; static const StyleAndName gStyles[] = { {SkPaint::kFill_Style, "Fill"}, {SkPaint::kStroke_Style, "Stroke"}, {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"}, }; struct CapAndName { SkPaint::Cap fCap; SkPaint::Join fJoin; const char* fName; }; static const CapAndName gCaps[] = { {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"}, {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"}, {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"} }; struct PathAndName { SkPath fPath; const char* fName; }; PathAndName path; path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1); path.fPath.cubicTo(40*SK_Scalar1, 20*SK_Scalar1, 60*SK_Scalar1, 20*SK_Scalar1, 75*SK_Scalar1, 10*SK_Scalar1); path.fPath.close(); path.fName = "moveTo-cubic-close"; SkPaint titlePaint; titlePaint.setColor(SK_ColorBLACK); titlePaint.setAntiAlias(true); sk_tool_utils::set_portable_typeface(&titlePaint); titlePaint.setTextSize(15 * SK_Scalar1); const char title[] = "Cubic Closed Drawn Into Rectangle Clips With " "Indicated Style, Fill and Linecaps, with stroke width 10"; canvas->drawText(title, strlen(title), 20 * SK_Scalar1, 20 * SK_Scalar1, titlePaint); SkRandom rand; SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1); canvas->save(); canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1); canvas->save(); for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) { if (0 < cap) { canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0); } canvas->save(); for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) { if (0 < fill) { canvas->translate(0, rect.height() + 40 * SK_Scalar1); } canvas->save(); for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) { if (0 < style) { canvas->translate(rect.width() + 40 * SK_Scalar1, 0); } SkColor color = 0xff007000; this->drawPath(path.fPath, canvas, color, rect, gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle, gFills[fill].fFill, SK_Scalar1*10); SkPaint rectPaint; rectPaint.setColor(SK_ColorBLACK); rectPaint.setStyle(SkPaint::kStroke_Style); rectPaint.setStrokeWidth(-1); rectPaint.setAntiAlias(true); canvas->drawRect(rect, rectPaint); SkPaint labelPaint; labelPaint.setColor(color); labelPaint.setAntiAlias(true); sk_tool_utils::set_portable_typeface(&labelPaint); labelPaint.setTextSize(10 * SK_Scalar1); canvas->drawText(gStyles[style].fName, strlen(gStyles[style].fName), 0, rect.height() + 12 * SK_Scalar1, labelPaint); canvas->drawText(gFills[fill].fName, strlen(gFills[fill].fName), 0, rect.height() + 24 * SK_Scalar1, labelPaint); canvas->drawText(gCaps[cap].fName, strlen(gCaps[cap].fName), 0, rect.height() + 36 * SK_Scalar1, labelPaint); } canvas->restore(); } canvas->restore(); } canvas->restore(); canvas->restore(); }
// Check for: // SAVE // CLIP_RECT // SAVE_LAYER // SAVE // CLIP_RECT // SAVE_LAYER // SAVE // CLIP_RECT // DRAWBITMAPRECTTORECT // RESTORE // RESTORE // RESTORE // RESTORE // RESTORE // where: // all the clipRect's are BW, nested, intersections // the drawBitmapRectToRect is a 1-1 copy from src to dest // the last (smallest) clip rect is a subset of the drawBitmapRectToRect's dest rect // all the saveLayer's paints can be rolled into the drawBitmapRectToRect's paint // This pattern is used by Google spreadsheet when drawing the toolbar buttons static bool check_7(SkDebugCanvas* canvas, int curCommand) { if (SAVE != canvas->getDrawCommandAt(curCommand)->getType() || canvas->getSize() <= curCommand+13 || CLIP_RECT != canvas->getDrawCommandAt(curCommand+1)->getType() || SAVE_LAYER != canvas->getDrawCommandAt(curCommand+2)->getType() || SAVE != canvas->getDrawCommandAt(curCommand+3)->getType() || CLIP_RECT != canvas->getDrawCommandAt(curCommand+4)->getType() || SAVE_LAYER != canvas->getDrawCommandAt(curCommand+5)->getType() || SAVE != canvas->getDrawCommandAt(curCommand+6)->getType() || CLIP_RECT != canvas->getDrawCommandAt(curCommand+7)->getType() || DRAW_BITMAP_RECT_TO_RECT != canvas->getDrawCommandAt(curCommand+8)->getType() || RESTORE != canvas->getDrawCommandAt(curCommand+9)->getType() || RESTORE != canvas->getDrawCommandAt(curCommand+10)->getType() || RESTORE != canvas->getDrawCommandAt(curCommand+11)->getType() || RESTORE != canvas->getDrawCommandAt(curCommand+12)->getType() || RESTORE != canvas->getDrawCommandAt(curCommand+13)->getType()) { return false; } SkClipRectCommand* clip0 = (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+1); SkSaveLayerCommand* saveLayer0 = (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2); SkClipRectCommand* clip1 = (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+4); SkSaveLayerCommand* saveLayer1 = (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5); SkClipRectCommand* clip2 = (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7); SkDrawBitmapRectCommand* dbmr = (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8); if (clip0->doAA() || clip1->doAA() || clip2->doAA()) { return false; } if (SkRegion::kIntersect_Op != clip0->op() || SkRegion::kIntersect_Op != clip1->op() || SkRegion::kIntersect_Op != clip2->op()) { return false; } if (!clip0->rect().contains(clip1->rect()) || !clip1->rect().contains(clip2->rect())) { return false; } // The src->dest mapping needs to be 1-to-1 if (NULL == dbmr->srcRect()) { if (dbmr->bitmap().width() != dbmr->dstRect().width() || dbmr->bitmap().height() != dbmr->dstRect().height()) { return false; } } else { if (dbmr->srcRect()->width() != dbmr->dstRect().width() || dbmr->srcRect()->height() != dbmr->dstRect().height()) { return false; } } if (!dbmr->dstRect().contains(clip2->rect())) { return false; } const SkPaint* saveLayerPaint0 = saveLayer0->paint(); const SkPaint* saveLayerPaint1 = saveLayer1->paint(); if ((NULL != saveLayerPaint0 && !is_simple(*saveLayerPaint0)) || (NULL != saveLayerPaint1 && !is_simple(*saveLayerPaint1))) { return false; } SkPaint* dbmrPaint = dbmr->paint(); if (NULL == dbmrPaint) { return true; } if (NULL != saveLayerPaint0) { SkColor layerColor0 = saveLayerPaint0->getColor() | 0xFF000000; // force opaque if (dbmrPaint->getColor() != layerColor0) { return false; } } if (NULL != saveLayerPaint1) { SkColor layerColor1 = saveLayerPaint1->getColor() | 0xFF000000; // force opaque if (dbmrPaint->getColor() != layerColor1) { return false; } } return true; }
void SkDevice::writePixels(const SkBitmap& bitmap, int x, int y, SkCanvas::Config8888 config8888) { if (bitmap.isNull() || bitmap.getTexture()) { return; } const SkBitmap* sprite = &bitmap; // check whether we have to handle a config8888 that doesn't match SkPMColor if (SkBitmap::kARGB_8888_Config == bitmap.config() && SkCanvas::kNative_Premul_Config8888 != config8888 && kPMColorAlias != config8888) { // We're going to have to convert from a config8888 to the native config // First we clip to the device bounds. SkBitmap dstBmp = this->accessBitmap(true); SkIRect spriteRect = SkIRect::MakeXYWH(x, y, bitmap.width(), bitmap.height()); SkIRect devRect = SkIRect::MakeWH(dstBmp.width(), dstBmp.height()); if (!spriteRect.intersect(devRect)) { return; } // write directly to the device if it has pixels and is SkPMColor bool drawSprite; if (SkBitmap::kARGB_8888_Config == dstBmp.config() && !dstBmp.isNull()) { // we can write directly to the dst when doing the conversion dstBmp.extractSubset(&dstBmp, spriteRect); drawSprite = false; } else { // we convert to a temporary bitmap and draw that as a sprite dstBmp.setConfig(SkBitmap::kARGB_8888_Config, spriteRect.width(), spriteRect.height()); if (!dstBmp.allocPixels()) { return; } drawSprite = true; } // copy pixels to dstBmp and convert from config8888 to native config. SkAutoLockPixels alp(bitmap); uint32_t* srcPixels = bitmap.getAddr32(spriteRect.fLeft - x, spriteRect.fTop - y); SkCopyConfig8888ToBitmap(dstBmp, srcPixels, bitmap.rowBytes(), config8888); if (drawSprite) { // we've clipped the sprite when we made a copy x = spriteRect.fLeft; y = spriteRect.fTop; sprite = &dstBmp; } else { return; } } SkPaint paint; paint.setXfermodeMode(SkXfermode::kSrc_Mode); SkRasterClip clip(SkIRect::MakeWH(fBitmap.width(), fBitmap.height())); SkDraw draw; draw.fRC = &clip; draw.fClip = &clip.bwRgn(); draw.fBitmap = &fBitmap; // canvas should have already called accessBitmap draw.fMatrix = &SkMatrix::I(); this->drawSprite(draw, *sprite, x, y, 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); SkSafeUnref(tmpPaint.setShader(shader)); canvas->drawVertices(SkCanvas::kTriangles_VertexMode, ptCount, verts, texs, (const SkColor*)colorA.ptr(), NULL, indices, indexCount, tmpPaint); }
static void do_fuzz(SkCanvas* canvas) { SkPath path; SkPaint paint; paint.setAntiAlias(true); for (int i=0;i<100;i++) { switch (R(33)) { case 0: paint.setColor(make_fill()); break; case 1: paint.setAlpha(gRand.nextU() & 0xFF); break; case 2: { SkBlendMode mode; switch (R(3)) { case 0: mode = SkBlendMode::kSrc; break; case 1: mode = SkBlendMode::kXor; break; case 2: default: // silence warning mode = SkBlendMode::kSrcOver; break; } paint.setBlendMode(mode); } break; case 3: switch (R(2)) { case 0: paint.setStrokeCap(SkPaint::kRound_Cap); break; case 1: paint.setStrokeCap(SkPaint::kButt_Cap); break; } break; case 4: switch (R(2)) { case 0: paint.setStrokeJoin(SkPaint::kRound_Join); break; case 1: paint.setStrokeJoin(SkPaint::kMiter_Join); break; } break; case 5: paint.setStrokeWidth(make_number()); break; case 6: paint.setStrokeMiter(make_number()); break; case 7: if (quick == true) break; paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle, make_number())); break; case 8: if (quick == true) break; //ctx.shadowColor = make_fill(); break; case 9: if (quick == true) break; //ctx.shadowOffsetX = make_number(); //ctx.shadowOffsetY = make_number(); break; case 10: canvas->restore(); break; case 11: canvas->rotate(make_number()); break; case 12: canvas->save(); break; case 13: canvas->scale(-1,-1); break; case 14: if (quick == true) break; if (transval == 0) { transval = make_number(); canvas->translate(transval,0); } else { canvas->translate(-transval,0); transval = 0; } break; case 15: { SkRect r; r.set(make_number(),make_number(),make_number(),make_number()); SkPaint::Style s = paint.getStyle(); paint.setStyle(SkPaint::kFill_Style); canvas->drawRect(r, paint); paint.setStyle(s); // clearrect } break; case 16: if (quick == true) break; // ctx.drawImage(imgObj,make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number()); break; case 17: { SkRect r; r.set(make_number(),make_number(),make_number(),make_number()); SkPaint::Style s = paint.getStyle(); paint.setStyle(SkPaint::kFill_Style); canvas->drawRect(r, paint); paint.setStyle(s); } break; case 18: path.reset(); break; case 19: // ctx.clip() is evil. break; case 20: path.close(); break; case 21: { SkPaint::Style s = paint.getStyle(); paint.setStyle(SkPaint::kFill_Style); canvas->drawPath(path, paint); paint.setStyle(s); } break; case 22: { SkPaint::Style s = paint.getStyle(); paint.setStyle(SkPaint::kFill_Style); canvas->drawPath(path, paint); paint.setStyle(s); } break; case 23: { SkRect r; r.set(make_number(),make_number(),make_number(),make_number()); SkPaint::Style s = paint.getStyle(); paint.setStyle(SkPaint::kStroke_Style); canvas->drawRect(r, paint); paint.setStyle(s); } break; case 24: if (quick == true) break; //ctx.arc(make_number(),make_number(),make_number(),make_number(),make_number(),true); break; case 25: if (quick == true) break; //ctx.arcTo(make_number(),make_number(),make_number(),make_number(),make_number()); break; case 26: if (quick == true) break; //ctx.bezierCurveTo(make_number(),make_number(),make_number(),make_number(),make_number(),make_number()); break; case 27: path.lineTo(make_number(),make_number()); break; case 28: path.moveTo(make_number(),make_number()); break; case 29: if (quick == true) break; path.quadTo(make_number(),make_number(),make_number(),make_number()); break; case 30: { if (quick == true) break; SkMatrix matrix; set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number()); canvas->concat(matrix); } break; case 31: { if (quick == true) break; SkMatrix matrix; set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number()); canvas->setMatrix(matrix); } break; case 32: if (scale_large == true) { switch (scval) { case 0: canvas->scale(-1000000000,1); canvas->scale(-1000000000,1); scval = 1; break; case 1: canvas->scale(-.000000001f,1); scval = 2; break; case 2: canvas->scale(-.000000001f,1); scval = 0; break; } } break; } } }
void onDraw(int loops, SkCanvas* canvas) override { SkRandom scaleRand; SkRandom transRand; SkRandom rotRand; int width, height; if (fUseAtlas) { width = kAtlasCellWidth; height = kAtlasCellHeight; } else { width = kCheckerboardWidth; height = kCheckerboardHeight; } SkPaint clearPaint; clearPaint.setColor(0xFF000000); clearPaint.setAntiAlias(true); SkISize size = canvas->getDeviceSize(); SkScalar maxTransX, maxTransY; if (kScale_Type == fType) { maxTransX = size.fWidth - (1.5f * width); maxTransY = size.fHeight - (1.5f * height); } else if (kTranslate_Type == fType) { maxTransX = SkIntToScalar(size.fWidth - width); maxTransY = SkIntToScalar(size.fHeight - height); } else { SkASSERT(kRotate_Type == fType); // Yes, some rotations will be off the top and left sides maxTransX = size.fWidth - SK_ScalarSqrt2 * height; maxTransY = size.fHeight - SK_ScalarSqrt2 * height; } SkMatrix mat; SkRect dst = { 0, 0, SkIntToScalar(width), SkIntToScalar(height) }; SkRect clearRect = { -1.0f, -1.0f, width+1.0f, height+1.0f }; SkPoint verts[4] = { // for drawVertices path { 0, 0 }, { 0, SkIntToScalar(height) }, { SkIntToScalar(width), SkIntToScalar(height) }, { SkIntToScalar(width), 0 } }; uint16_t indices[6] = { 0, 1, 2, 0, 2, 3 }; SkPaint p; p.setColor(0xFF000000); p.setFilterQuality(kLow_SkFilterQuality); SkPaint p2; // for drawVertices path p2.setColor(0xFF000000); p2.setFilterQuality(kLow_SkFilterQuality); p2.setShader(SkShader::CreateBitmapShader(fAtlas, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode))->unref(); for (int i = 0; i < loops; ++i, ++fNumSaved) { if (0 == i % kNumBeforeClear) { if (kPartial_Clear == fClear) { for (int j = 0; j < fNumSaved; ++j) { canvas->setMatrix(SkMatrix::I()); mat.setTranslate(fSaved[j][0], fSaved[j][1]); if (kScale_Type == fType) { mat.preScale(fSaved[j][2], fSaved[j][2]); } else if (kRotate_Type == fType) { mat.preRotate(fSaved[j][2]); } canvas->concat(mat); canvas->drawRect(clearRect, clearPaint); } } else { canvas->clear(0xFF000000); } fNumSaved = 0; } SkASSERT(fNumSaved < kNumBeforeClear); canvas->setMatrix(SkMatrix::I()); fSaved[fNumSaved][0] = transRand.nextRangeScalar(0.0f, maxTransX); fSaved[fNumSaved][1] = transRand.nextRangeScalar(0.0f, maxTransY); if (fAligned) { // make the translations integer aligned fSaved[fNumSaved][0] = SkScalarFloorToScalar(fSaved[fNumSaved][0]); fSaved[fNumSaved][1] = SkScalarFloorToScalar(fSaved[fNumSaved][1]); } mat.setTranslate(fSaved[fNumSaved][0], fSaved[fNumSaved][1]); if (kScale_Type == fType) { fSaved[fNumSaved][2] = scaleRand.nextRangeScalar(0.5f, 1.5f); mat.preScale(fSaved[fNumSaved][2], fSaved[fNumSaved][2]); } else if (kRotate_Type == fType) { fSaved[fNumSaved][2] = rotRand.nextRangeScalar(0.0f, 360.0f); mat.preRotate(fSaved[fNumSaved][2]); } canvas->concat(mat); if (fUseAtlas) { const int curCell = i % (kNumAtlasedX * kNumAtlasedY); SkIRect src = fAtlasRects[curCell % (kNumAtlasedX)][curCell / (kNumAtlasedX)]; if (fUseDrawVertices) { SkPoint uvs[4] = { { SkIntToScalar(src.fLeft), SkIntToScalar(src.fBottom) }, { SkIntToScalar(src.fLeft), SkIntToScalar(src.fTop) }, { SkIntToScalar(src.fRight), SkIntToScalar(src.fTop) }, { SkIntToScalar(src.fRight), SkIntToScalar(src.fBottom) }, }; canvas->drawVertices(SkCanvas::kTriangles_VertexMode, 4, verts, uvs, nullptr, nullptr, indices, 6, p2); } else { canvas->drawBitmapRect(fAtlas, src, dst, &p, SkCanvas::kFast_SrcRectConstraint); } } else { canvas->drawBitmapRect(fCheckerboard, dst, &p); } } }
static void test_bigblur(SkCanvas* canvas) { canvas->drawColor(SK_ColorBLACK); SkBitmap orig, mask; SkImageDecoder::DecodeFile("/skimages/app_icon.png", &orig); SkMaskFilter* mf = SkBlurMaskFilter::Create(8, SkBlurMaskFilter::kNormal_BlurStyle); SkPaint paint; paint.setMaskFilter(mf)->unref(); SkIPoint offset; orig.extractAlpha(&mask, &paint, &offset); paint.setColor(0xFFBB8800); paint.setColor(SK_ColorWHITE); int i; canvas->save(); float gamma = 0.8; for (i = 0; i < 5; i++) { paint.setMaskFilter(SkTableMaskFilter::CreateGamma(gamma))->unref(); canvas->drawBitmap(mask, 0, 0, &paint); paint.setMaskFilter(NULL); canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint); gamma -= 0.1; canvas->translate(120, 0); } canvas->restore(); canvas->translate(0, 160); for (i = 0; i < 5; i++) { paint.setMaskFilter(SkTableMaskFilter::CreateClip(i*30, 255 - 20))->unref(); canvas->drawBitmap(mask, 0, 0, &paint); paint.setMaskFilter(NULL); canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint); canvas->translate(120, 0); } #if 0 paint.setColor(0xFFFFFFFF); canvas->drawBitmap(mask, 0, 0, &paint); paint.setMaskFilter(NULL); canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint); canvas->translate(120, 0); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint); canvas->translate(120, 0); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint); canvas->translate(120, 0); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint); canvas->translate(120, 0); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(mask, 0, 0, &paint); canvas->drawBitmap(orig, -offset.fX, -offset.fY, &paint); #endif }
static void generateMask(const SkMask& mask, const SkPath& path, const SkMaskGamma::PreBlend& maskPreBlend) { SkPaint paint; int srcW = mask.fBounds.width(); int srcH = mask.fBounds.height(); int dstW = srcW; int dstH = srcH; int dstRB = mask.fRowBytes; SkMatrix matrix; matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft), -SkIntToScalar(mask.fBounds.fTop)); paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat); switch (mask.fFormat) { case SkMask::kBW_Format: dstRB = 0; // signals we need a copy break; case SkMask::kA8_Format: break; case SkMask::kLCD16_Format: // TODO: trigger off LCD orientation dstW = 4*dstW - 8; matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1), -SkIntToScalar(mask.fBounds.fTop)); matrix.postScale(SkIntToScalar(4), SK_Scalar1); dstRB = 0; // signals we need a copy break; default: SkDEBUGFAIL("unexpected mask format"); } SkRasterClip clip; clip.setRect(SkIRect::MakeWH(dstW, dstH)); const SkImageInfo info = SkImageInfo::MakeA8(dstW, dstH); SkAutoPixmapStorage dst; if (0 == dstRB) { if (!dst.tryAlloc(info)) { // can't allocate offscreen, so empty the mask and return sk_bzero(mask.fImage, mask.computeImageSize()); return; } } else { dst.reset(info, mask.fImage, dstRB); } sk_bzero(dst.writable_addr(), dst.getSafeSize()); SkDraw draw; draw.fDst = dst; draw.fRC = &clip; draw.fMatrix = &matrix; draw.drawPath(path, paint); switch (mask.fFormat) { case SkMask::kBW_Format: packA8ToA1(mask, dst.addr8(0, 0), dst.rowBytes()); break; case SkMask::kA8_Format: if (maskPreBlend.isApplicable()) { applyLUTToA8Mask(mask, maskPreBlend.fG); } break; case SkMask::kLCD16_Format: if (maskPreBlend.isApplicable()) { pack4xHToLCD16<true>(dst, mask, maskPreBlend); } else { pack4xHToLCD16<false>(dst, mask, maskPreBlend); } break; default: break; } }
MeasureView() { fPaint.setAntiAlias(true); fPaint.setTextSize(SkIntToScalar(64)); this->setBGColor(0xFFDDDDDD); }
void onDrawContent(SkCanvas* canvas) override { bool sizeChanged = false; if (canvas->getDeviceSize() != fSize) { fSize = canvas->getDeviceSize(); sizeChanged = true; } SkScalar ySpread = SkIntToScalar(fSize.fHeight / 20); SkScalar height = SkIntToScalar(fSize.fHeight); if (sizeChanged) { int dataPointCount = SkMax32(fSize.fWidth / kPixelsPerTick + 1, 2); for (int i = 0; i < kNumGraphs; ++i) { SkScalar y = (kNumGraphs - i) * (height - ySpread) / (kNumGraphs + 1); fData[i].reset(); gen_data(y, ySpread, dataPointCount, fData + i); } } canvas->clear(0xFFE0F0E0); static SkRandom colorRand; static SkColor gColors[kNumGraphs] = { 0x0 }; if (0 == gColors[0]) { for (int i = 0; i < kNumGraphs; ++i) { gColors[i] = colorRand.nextU() | 0xff000000; } } SkPath plotPath; SkPath fillPath; static const SkScalar kStrokeWidth = SkIntToScalar(2); SkPaint plotPaint; SkPaint fillPaint; plotPaint.setAntiAlias(true); plotPaint.setStyle(SkPaint::kStroke_Style); plotPaint.setStrokeWidth(kStrokeWidth); plotPaint.setStrokeCap(SkPaint::kRound_Cap); plotPaint.setStrokeJoin(SkPaint::kRound_Join); fillPaint.setAntiAlias(true); fillPaint.setStyle(SkPaint::kFill_Style); SkTDArray<SkScalar>* prevData = nullptr; for (int i = 0; i < kNumGraphs; ++i) { gen_paths(fData[i], prevData, height, 0, SkIntToScalar(kPixelsPerTick), fShift, &plotPath, &fillPath); // Make the fills partially transparent fillPaint.setColor((gColors[i] & 0x00ffffff) | 0x80000000); canvas->drawPath(fillPath, fillPaint); plotPaint.setColor(gColors[i]); canvas->drawPath(plotPath, plotPaint); prevData = fData + i; } fShift += kShiftPerFrame; this->inval(nullptr); }
virtual void onDrawContent(SkCanvas* canvas) { canvas->translate(fPaint.getTextSize(), fPaint.getTextSize()); doMeasure(canvas, fPaint, "Hamburgefons"); }
AARectModesGM () { fBGPaint.setShader(make_bg_shader())->unref(); }
// Make sure our blits are invariant with the width of the blit (i.e. that // special case for 8 at a time have the same results as narrower blits) static void test_diagonal(skiatest::Reporter* reporter) { static const int W = 64; static const int H = W; static const SkBitmap::Config gDstConfig[] = { SkBitmap::kARGB_8888_Config, SkBitmap::kRGB_565_Config, // SkBitmap::kARGB_4444_Config, // SkBitmap::kA8_Config, }; static const SkColor gDstBG[] = { 0, 0xFFFFFFFF }; SkPaint paint; SkBitmap srcBM; srcBM.setConfig(SkBitmap::kARGB_8888_Config, W, H); srcBM.allocPixels(); SkRect srcR = { 0, 0, SkIntToScalar(srcBM.width()), SkIntToScalar(srcBM.height()) }; // cons up a mesh to draw the bitmap with Mesh mesh(srcBM, &paint); for (size_t i = 0; i < SK_ARRAY_COUNT(gDstConfig); i++) { SkBitmap dstBM0, dstBM1; dstBM0.setConfig(gDstConfig[i], W, H); dstBM1.setConfig(gDstConfig[i], W, H); dstBM0.allocPixels(); dstBM1.allocPixels(); SkCanvas canvas0(dstBM0); SkCanvas canvas1(dstBM1); SkColor bgColor; for (size_t j = 0; j < SK_ARRAY_COUNT(gDstBG); j++) { bgColor = gDstBG[j]; for (int c = 0; c <= 0xFF; c++) { srcBM.eraseARGB(0xFF, c, c, c); for (int k = 0; k < 4; k++) { bool dither = (k & 1) != 0; uint8_t alpha = (k & 2) ? 0x80 : 0xFF; paint.setDither(dither); paint.setAlpha(alpha); dstBM0.eraseColor(bgColor); dstBM1.eraseColor(bgColor); canvas0.drawRect(srcR, paint); mesh.draw(&canvas1, &paint); if (!gOnce && false) { save_bm(dstBM0, "drawBitmap.png"); save_bm(dstBM1, "drawMesh.png"); gOnce = true; } if (memcmp(dstBM0.getPixels(), dstBM1.getPixels(), dstBM0.getSize())) { SkString str; str.printf("Diagonal config=%s bg=0x%x dither=%d alpha=0x%x src=0x%x", gConfigName[gDstConfig[i]], bgColor, dither, alpha, c); reporter->reportFailed(str); } } } } } }
virtual void onDrawContent(SkCanvas* canvas) { canvas->translate(SkIntToScalar(10), SkIntToScalar(10)); SkPaint bluePaint; bluePaint.setARGB(0xff, 0x0, 0x0, 0xff); SkPaint bmpPaint; SkShader* bmpShader = SkShader::CreateBitmapShader(fBitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); bmpPaint.setShader(bmpShader); bmpShader->unref(); bluePaint.setStrokeWidth(3); bmpPaint.setStrokeWidth(3); SkPaint paints[] = { bluePaint, bmpPaint }; SkRect rect; SkScalar dx = SkIntToScalar(80); SkScalar dy = SkIntToScalar(100); SkMatrix matrix; for (size_t p = 0; p < SK_ARRAY_COUNT(paints); ++p) { for (int stroke = 0; stroke < 2; ++stroke) { paints[p].setStyle(stroke ? SkPaint::kStroke_Style : SkPaint::kFill_Style); for (int a = 0; a < 3; ++ a) { paints[p].setAntiAlias(a > 0); paints[p].setAlpha(a > 1 ? 0x80 : 0xff); canvas->save(); rect = SkRect::MakeLTRB(SkFloatToScalar(0.f), SkFloatToScalar(0.f), SkFloatToScalar(40.f), SkFloatToScalar(40.f)); canvas->drawRect(rect, paints[p]); canvas->translate(dx, 0); rect = SkRect::MakeLTRB(SkFloatToScalar(0.5f), SkFloatToScalar(0.5f), SkFloatToScalar(40.5f), SkFloatToScalar(40.5f)); canvas->drawRect(rect, paints[p]); canvas->translate(dx, 0); rect = SkRect::MakeLTRB(SkFloatToScalar(0.5f), SkFloatToScalar(0.5f), SkFloatToScalar(40.f), SkFloatToScalar(40.f)); canvas->drawRect(rect, paints[p]); canvas->translate(dx, 0); rect = SkRect::MakeLTRB(SkFloatToScalar(0.75f), SkFloatToScalar(0.75f), SkFloatToScalar(40.75f), SkFloatToScalar(40.75f)); canvas->drawRect(rect, paints[p]); canvas->translate(dx, 0); canvas->save(); canvas->translate(SkFloatToScalar(.33f), SkFloatToScalar(.67f)); rect = SkRect::MakeLTRB(SkFloatToScalar(0.0f), SkFloatToScalar(0.0f), SkFloatToScalar(40.0f), SkFloatToScalar(40.0f)); canvas->drawRect(rect, paints[p]); canvas->restore(); canvas->translate(dx, 0); canvas->save(); matrix.setRotate(SkFloatToScalar(45.f)); canvas->concat(matrix); canvas->translate(SkFloatToScalar(20.0f / sqrtf(2.f)), SkFloatToScalar(20.0f / sqrtf(2.f))); rect = SkRect::MakeLTRB(SkFloatToScalar(-20.0f), SkFloatToScalar(-20.0f), SkFloatToScalar(20.0f), SkFloatToScalar(20.0f)); canvas->drawRect(rect, paints[p]); canvas->restore(); canvas->translate(dx, 0); canvas->save(); canvas->rotate(SkFloatToScalar(90.f)); rect = SkRect::MakeLTRB(SkFloatToScalar(0.0f), SkFloatToScalar(0.0f), SkFloatToScalar(40.0f), SkFloatToScalar(-40.0f)); canvas->drawRect(rect, paints[p]); canvas->restore(); canvas->translate(dx, 0); canvas->save(); canvas->rotate(SkFloatToScalar(90.f)); rect = SkRect::MakeLTRB(SkFloatToScalar(0.5f), SkFloatToScalar(0.5f), SkFloatToScalar(40.5f), SkFloatToScalar(-40.5f)); canvas->drawRect(rect, paints[p]); canvas->restore(); canvas->translate(dx, 0); canvas->save(); matrix.setScale(SkFloatToScalar(-1.f), SkFloatToScalar(-1.f)); canvas->concat(matrix); rect = SkRect::MakeLTRB(SkFloatToScalar(0.5f), SkFloatToScalar(0.5f), SkFloatToScalar(-40.5f), SkFloatToScalar(-40.5f)); canvas->drawRect(rect, paints[p]); canvas->restore(); canvas->translate(dx, 0); canvas->save(); matrix.setScale(SkFloatToScalar(2.1f), SkFloatToScalar(4.1f)); canvas->concat(matrix); rect = SkRect::MakeLTRB(SkFloatToScalar(0.1f), SkFloatToScalar(0.1f), SkFloatToScalar(19.1f), SkFloatToScalar(9.1f)); canvas->drawRect(rect, paints[p]); canvas->restore(); canvas->translate(dx, 0); canvas->restore(); canvas->translate(0, dy); } } } }
void GraphicsContext::drawLineForTextChecking(const IntPoint& pt, int width, TextCheckingLineStyle style) { if (paintingDisabled()) return; platformContext()->prepareForSoftwareDraw(); // Create the pattern we'll use to draw the underline. static SkBitmap* misspellBitmap = 0; if (!misspellBitmap) { // We use a 2-pixel-high misspelling indicator because that seems to be // what WebKit is designed for, and how much room there is in a typical // page for it. const int rowPixels = 32; // Must be multiple of 4 for pattern below. const int colPixels = 2; misspellBitmap = new SkBitmap; misspellBitmap->setConfig(SkBitmap::kARGB_8888_Config, rowPixels, colPixels); misspellBitmap->allocPixels(); misspellBitmap->eraseARGB(0, 0, 0, 0); const uint32_t lineColor = 0xFFFF0000; // Opaque red. const uint32_t antiColor = 0x60600000; // Semitransparent red. // Pattern: X o o X o o X // o X o o X o uint32_t* row1 = misspellBitmap->getAddr32(0, 0); uint32_t* row2 = misspellBitmap->getAddr32(0, 1); for (int x = 0; x < rowPixels; x++) { switch (x % 4) { case 0: row1[x] = lineColor; break; case 1: row1[x] = antiColor; row2[x] = antiColor; break; case 2: row2[x] = lineColor; break; case 3: row1[x] = antiColor; row2[x] = antiColor; break; } } } // Offset it vertically by 1 so that there's some space under the text. SkScalar originX = SkIntToScalar(pt.x()); SkScalar originY = SkIntToScalar(pt.y()) + 1; // Make a shader for the bitmap with an origin of the box we'll draw. This // shader is refcounted and will have an initial refcount of 1. SkShader* shader = SkShader::CreateBitmapShader( *misspellBitmap, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); SkMatrix matrix; matrix.reset(); matrix.postTranslate(originX, originY); shader->setLocalMatrix(matrix); // Assign the shader to the paint & release our reference. The paint will // now own the shader and the shader will be destroyed when the paint goes // out of scope. SkPaint paint; paint.setShader(shader); shader->unref(); SkRect rect; rect.set(originX, originY, originX + SkIntToScalar(width), originY + SkIntToScalar(misspellBitmap->height())); platformContext()->canvas()->drawRect(rect, paint); }
void GrDistanceFieldTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPaint, const char text[], size_t byteLength, SkScalar x, SkScalar y) { SkASSERT(byteLength == 0 || text != NULL); // nothing to draw if (text == NULL || byteLength == 0) { return; } SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); SkAutoGlyphCache autoCache(skPaint, &fDeviceProperties, NULL); SkGlyphCache* cache = autoCache.getCache(); SkTArray<SkScalar> positions; const char* textPtr = text; SkFixed stopX = 0; SkFixed stopY = 0; SkFixed origin; switch (skPaint.getTextAlign()) { case SkPaint::kRight_Align: origin = SK_Fixed1; break; case SkPaint::kCenter_Align: origin = SK_FixedHalf; break; case SkPaint::kLeft_Align: origin = 0; break; default: SkFAIL("Invalid paint origin"); return; } SkAutoKern autokern; const char* stop = text + byteLength; while (textPtr < stop) { // don't need x, y here, since all subpixel variants will have the // same advance const SkGlyph& glyph = glyphCacheProc(cache, &textPtr, 0, 0); SkFixed width = glyph.fAdvanceX + autokern.adjust(glyph); positions.push_back(SkFixedToScalar(stopX + SkFixedMul_portable(origin, width))); SkFixed height = glyph.fAdvanceY; positions.push_back(SkFixedToScalar(stopY + SkFixedMul_portable(origin, height))); stopX += width; stopY += height; } SkASSERT(textPtr == stop); // now adjust starting point depending on alignment SkScalar alignX = SkFixedToScalar(stopX); SkScalar alignY = SkFixedToScalar(stopY); if (skPaint.getTextAlign() == SkPaint::kCenter_Align) { alignX = SkScalarHalf(alignX); alignY = SkScalarHalf(alignY); } else if (skPaint.getTextAlign() == SkPaint::kLeft_Align) { alignX = 0; alignY = 0; } x -= alignX; y -= alignY; SkPoint offset = SkPoint::Make(x, y); this->drawPosText(paint, skPaint, text, byteLength, positions.begin(), 2, offset); }
static void generateMask(const SkMask& mask, const SkPath& path, const SkMaskGamma::PreBlend& maskPreBlend) { SkPaint paint; int srcW = mask.fBounds.width(); int srcH = mask.fBounds.height(); int dstW = srcW; int dstH = srcH; int dstRB = mask.fRowBytes; SkMatrix matrix; matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft), -SkIntToScalar(mask.fBounds.fTop)); SkBitmap::Config config = SkBitmap::kA8_Config; paint.setAntiAlias(SkMask::kBW_Format != mask.fFormat); switch (mask.fFormat) { case SkMask::kBW_Format: dstRB = 0; // signals we need a copy break; case SkMask::kA8_Format: break; case SkMask::kLCD16_Format: case SkMask::kLCD32_Format: // TODO: trigger off LCD orientation dstW = 4*dstW - 8; matrix.setTranslate(-SkIntToScalar(mask.fBounds.fLeft + 1), -SkIntToScalar(mask.fBounds.fTop)); matrix.postScale(SkIntToScalar(4), SK_Scalar1); dstRB = 0; // signals we need a copy break; default: SkDEBUGFAIL("unexpected mask format"); } SkRasterClip clip; clip.setRect(SkIRect::MakeWH(dstW, dstH)); SkBitmap bm; bm.setConfig(config, dstW, dstH, dstRB); if (0 == dstRB) { if (!bm.allocPixels()) { // can't allocate offscreen, so empty the mask and return sk_bzero(mask.fImage, mask.computeImageSize()); return; } bm.lockPixels(); } else { bm.setPixels(mask.fImage); } sk_bzero(bm.getPixels(), bm.getSafeSize()); SkDraw draw; draw.fRC = &clip; draw.fClip = &clip.bwRgn(); draw.fMatrix = &matrix; draw.fBitmap = &bm; draw.drawPath(path, paint); switch (mask.fFormat) { case SkMask::kBW_Format: packA8ToA1(mask, bm.getAddr8(0, 0), bm.rowBytes()); break; case SkMask::kA8_Format: if (maskPreBlend.isApplicable()) { applyLUTToA8Mask(mask, maskPreBlend.fG); } break; case SkMask::kLCD16_Format: if (maskPreBlend.isApplicable()) { pack4xHToLCD16<true>(bm, mask, maskPreBlend); } else { pack4xHToLCD16<false>(bm, mask, maskPreBlend); } break; case SkMask::kLCD32_Format: if (maskPreBlend.isApplicable()) { pack4xHToLCD32<true>(bm, mask, maskPreBlend); } else { pack4xHToLCD32<false>(bm, mask, maskPreBlend); } break; default: break; } }
void draw(SkCanvas* canvas) { SkPaint paint; SkDebugf("12 %c= default text size\n", 12 == paint.getTextSize() ? '=' : '!'); }
virtual void onDraw(SkCanvas* canvas) { canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); const struct { SkXfermode::Mode fMode; const char* fLabel; } gModes[] = { { SkXfermode::kClear_Mode, "Clear" }, { SkXfermode::kSrc_Mode, "Src" }, { SkXfermode::kDst_Mode, "Dst" }, { SkXfermode::kSrcOver_Mode, "SrcOver" }, { SkXfermode::kDstOver_Mode, "DstOver" }, { SkXfermode::kSrcIn_Mode, "SrcIn" }, { SkXfermode::kDstIn_Mode, "DstIn" }, { SkXfermode::kSrcOut_Mode, "SrcOut" }, { SkXfermode::kDstOut_Mode, "DstOut" }, { SkXfermode::kSrcATop_Mode, "SrcATop" }, { SkXfermode::kDstATop_Mode, "DstATop" }, { SkXfermode::kXor_Mode, "Xor" }, { SkXfermode::kPlus_Mode, "Plus" }, { SkXfermode::kMultiply_Mode, "Multiply" }, { SkXfermode::kScreen_Mode, "Screen" }, { SkXfermode::kOverlay_Mode, "Overlay" }, { SkXfermode::kDarken_Mode, "Darken" }, { SkXfermode::kLighten_Mode, "Lighten" }, { SkXfermode::kColorDodge_Mode, "ColorDodge" }, { SkXfermode::kColorBurn_Mode, "ColorBurn" }, { SkXfermode::kHardLight_Mode, "HardLight" }, { SkXfermode::kSoftLight_Mode, "SoftLight" }, { SkXfermode::kDifference_Mode, "Difference" }, { SkXfermode::kExclusion_Mode, "Exclusion" }, }; const SkScalar w = SkIntToScalar(W); const SkScalar h = SkIntToScalar(H); SkShader* s = SkShader::CreateBitmapShader(fBG, SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode); SkMatrix m; m.setScale(SkIntToScalar(6), SkIntToScalar(6)); s->setLocalMatrix(m); SkPaint labelP; labelP.setAntiAlias(true); labelP.setTextAlign(SkPaint::kCenter_Align); const int W = 5; SkScalar x0 = 0; for (int twice = 0; twice < 2; twice++) { SkScalar x = x0, y = 0; for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) { SkXfermode* mode = SkXfermode::Create(gModes[i].fMode); SkAutoUnref aur(mode); SkRect r; r.set(x, y, x+w, y+h); SkPaint p; p.setStyle(SkPaint::kFill_Style); p.setShader(s); canvas->drawRect(r, p); canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag); draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop); canvas->restore(); r.inset(-SK_ScalarHalf, -SK_ScalarHalf); p.setStyle(SkPaint::kStroke_Style); p.setShader(NULL); canvas->drawRect(r, p); #if 1 canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel), x + w/2, y - labelP.getTextSize()/2, labelP); #endif x += w + SkIntToScalar(10); if ((i % W) == W - 1) { x = x0; y += h + SkIntToScalar(30); } } x0 += SkIntToScalar(400); } s->unref(); }
virtual void onDrawContent(SkCanvas* canvas) { if (fSocket) { if (fSocket->isConnected()) { if (fSync) { int count = 0; while (fSocket->readPacket(readData, this) > 0 && count < MAX_READ_PER_FRAME) ++count; } else fSocket->readPacket(readData, this); } else fSocket->connectToServer(); } size_t bytesRead = 0; SkGPipeReader::Status status; SkCanvas bufferCanvas(fBase); SkCanvas* tempCanvas; while (fTotalBytesRead < fData.count()) { if (fVector) tempCanvas = canvas; else tempCanvas = &bufferCanvas; SkGPipeReader reader(tempCanvas); status = reader.playback(fData.begin() + fTotalBytesRead, fData.count() - fTotalBytesRead, &bytesRead); SkASSERT(SkGPipeReader::kError_Status != status); fTotalBytesRead += bytesRead; } if (fVector) fTotalBytesRead = 0; else canvas->drawBitmap(fBase, 0, 0, NULL); size_t totalBytesRead = 0; while (totalBytesRead < fBuffer.count()) { SkGPipeReader reader(canvas); status = reader.playback(fBuffer.begin() + totalBytesRead, fBuffer.count() - totalBytesRead, &bytesRead); SkASSERT(SkGPipeReader::kError_Status != status); totalBytesRead += bytesRead; } SkNetPipeController controller(canvas); SkGPipeWriter writer; SkCanvas* writerCanvas = writer.startRecording(&controller, SkGPipeWriter::kCrossProcess_Flag); //controller.disablePlayback(); SkPaint p; p.setColor(fPalette->getColor()); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(fBrushSize); p.setStrokeCap(SkPaint::kRound_Cap); p.setStrokeJoin(SkPaint::kRound_Join); p.setAntiAlias(fAA); p.setPathEffect(new SkCornerPathEffect(55))->unref(); writerCanvas->drawPath(fCurrLine, p); writer.endRecording(); controller.writeToSocket(fSocket, fType); if (fType == SkSocket::kPipeAppend_type && fSocket) { fSocket->suspendWrite(); fCurrLine.reset(); } this->inval(NULL); }
int main(void) { GLFWwindow* window; glfwSetErrorCallback(error_callback); if (!glfwInit()) { exit(EXIT_FAILURE); } glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_SRGB_CAPABLE, GL_TRUE); window = glfwCreateWindow(kWidth, kHeight, "Simple example", NULL, NULL); if (!window) { glfwTerminate(); exit(EXIT_FAILURE); } glfwMakeContextCurrent(window); init_skia(kWidth, kHeight); SkAutoTUnref<SkImage> atlas; SkRSXform xform[kGrid*kGrid+1]; SkRect tex[kGrid*kGrid+1]; WallTimer timer; float times[32]; int currentTime; SkAutoTUnref<SkData> imageData(SkData::NewFromFileName("ship.png")); atlas.reset(SkImage::NewFromEncoded(imageData)); if (!atlas) { SkDebugf("\nCould not decode file ship.png\n"); cleanup_skia(); glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_FAILURE); } SkScalar anchorX = atlas->width()*0.5f; SkScalar anchorY = atlas->height()*0.5f; int currIndex = 0; for (int x = 0; x < kGrid; x++) { for (int y = 0; y < kGrid; y++) { float xPos = (x / (kGrid - 1.0)) * kWidth; float yPos = (y / (kGrid - 1.0)) * kWidth; tex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f, atlas->width(), atlas->height()); xform[currIndex] = SkRSXform::MakeFromRadians(2.0f, SK_ScalarPI*0.5f, xPos, yPos, anchorX, anchorY); currIndex++; } } tex[currIndex] = SkRect::MakeLTRB(0.0f, 0.0f, atlas->width(), atlas->height()); xform[currIndex] = SkRSXform::MakeFromRadians(2.0f, SK_ScalarPI*0.5f, kWidth*0.5f, kHeight*0.5f, anchorX, anchorY); currentTime = 0; glfwSwapInterval(1); glfwSetKeyCallback(window, key_callback); // Draw to the surface via its SkCanvas. SkCanvas* canvas = sSurface->getCanvas(); // We don't manage this pointer's lifetime. SkPaint paint; paint.setFilterQuality(kLow_SkFilterQuality); paint.setColor(SK_ColorWHITE); paint.setTextSize(15.0f); while (!glfwWindowShouldClose(window)) { const float kCosDiff = 0.99984769515f; const float kSinDiff = 0.01745240643f; timer.start(); glfwPollEvents(); float meanTime = 0.0f; for (int i = 0; i < 32; ++i) { meanTime += times[i]; } meanTime /= 32.f; char outString[64]; float fps = 1000.f/meanTime; sprintf(outString, "fps: %f ms: %f", fps, meanTime); for (int i = 0; i < kGrid*kGrid+1; ++i) { SkScalar c = xform[i].fSCos; SkScalar s = xform[i].fSSin; SkScalar dx = c*anchorX - s*anchorY; SkScalar dy = s*anchorX + c*anchorY; xform[i].fSCos = kCosDiff*c - kSinDiff*s; xform[i].fSSin = kSinDiff*c + kCosDiff*s; dx -= xform[i].fSCos*anchorX - xform[i].fSSin*anchorY; dy -= xform[i].fSSin*anchorX + xform[i].fSCos*anchorY; xform[i].fTx += dx; xform[i].fTy += dy; } canvas->clear(SK_ColorBLACK); canvas->drawAtlas(atlas, xform, tex, nullptr, kGrid*kGrid+1, SkXfermode::kSrcOver_Mode, nullptr, &paint); canvas->drawText(outString, strlen(outString), 100.f, 100.f, paint); canvas->flush(); timer.end(); times[currentTime] = (float)(timer.fWall); currentTime = (currentTime + 1) & 0x1f; glfwSwapBuffers(window); } cleanup_skia(); glfwDestroyWindow(window); glfwTerminate(); exit(EXIT_SUCCESS); }
void TestShell::dump() { WebScriptController::flushConsoleMessages(); // Dump the requested representation. WebFrame* frame = m_webView->mainFrame(); if (!frame) return; bool shouldDumpAsText = m_layoutTestController->shouldDumpAsText(); bool shouldDumpAsAudio = m_layoutTestController->shouldDumpAsAudio(); bool shouldGeneratePixelResults = m_layoutTestController->shouldGeneratePixelResults(); bool shouldDumpAsPrinted = m_layoutTestController->isPrinting(); bool dumpedAnything = false; if (shouldDumpAsAudio) { m_printer->handleAudioHeader(); const WebKit::WebArrayBufferView& webArrayBufferView = m_layoutTestController->audioData(); printf("Content-Length: %d\n", webArrayBufferView.byteLength()); if (fwrite(webArrayBufferView.baseAddress(), 1, webArrayBufferView.byteLength(), stdout) != webArrayBufferView.byteLength()) FATAL("Short write to stdout, disk full?\n"); printf("\n"); m_printer->handleTestFooter(true); fflush(stdout); fflush(stderr); return; } if (m_params.dumpTree) { dumpedAnything = true; m_printer->handleTextHeader(); // Text output: the test page can request different types of output // which we handle here. if (!shouldDumpAsText) { // Plain text pages should be dumped as text string mimeType = frame->dataSource()->response().mimeType().utf8(); if (mimeType == "text/plain") { shouldDumpAsText = true; shouldGeneratePixelResults = false; } } if (shouldDumpAsText) { bool recursive = m_layoutTestController->shouldDumpChildFramesAsText(); string dataUtf8 = shouldDumpAsPrinted ? dumpFramesAsPrintedText(frame, recursive) : dumpFramesAsText(frame, recursive); if (fwrite(dataUtf8.c_str(), 1, dataUtf8.size(), stdout) != dataUtf8.size()) FATAL("Short write to stdout, disk full?\n"); } else { WebFrame::RenderAsTextControls renderTextBehavior = WebFrame::RenderAsTextNormal; if (shouldDumpAsPrinted) renderTextBehavior |= WebFrame::RenderAsTextPrinting; if (m_params.debugRenderTree) renderTextBehavior |= WebFrame::RenderAsTextDebug; printf("%s", frame->renderTreeAsText(renderTextBehavior).utf8().data()); bool recursive = m_layoutTestController->shouldDumpChildFrameScrollPositions(); dumpFrameScrollPosition(frame, recursive); } if (m_layoutTestController->shouldDumpBackForwardList()) printf("%s", dumpAllBackForwardLists().c_str()); } if (dumpedAnything && m_params.printSeparators) m_printer->handleTextFooter(); if (m_params.dumpPixels && shouldGeneratePixelResults) { // Image output: we write the image data to the file given on the // command line (for the dump pixels argument), and the MD5 sum to // stdout. dumpedAnything = true; m_webView->layout(); if (m_layoutTestController->testRepaint()) { WebSize viewSize = m_webView->size(); int width = viewSize.width; int height = viewSize.height; if (m_layoutTestController->sweepHorizontally()) { for (WebRect column(0, 0, 1, height); column.x < width; column.x++) m_webViewHost->paintRect(column); } else { for (WebRect line(0, 0, width, 1); line.y < height; line.y++) m_webViewHost->paintRect(line); } } else if (m_layoutTestController->isPrinting()) m_webViewHost->paintPagesWithBoundaries(); else m_webViewHost->paintInvalidatedRegion(); // See if we need to draw the selection bounds rect. Selection bounds // rect is the rect enclosing the (possibly transformed) selection. // The rect should be drawn after everything is laid out and painted. if (m_layoutTestController->shouldDumpSelectionRect()) { // If there is a selection rect - draw a red 1px border enclosing rect WebRect wr = frame->selectionBoundsRect(); if (!wr.isEmpty()) { // Render a red rectangle bounding selection rect SkPaint paint; paint.setColor(0xFFFF0000); // Fully opaque red paint.setStyle(SkPaint::kStroke_Style); paint.setFlags(SkPaint::kAntiAlias_Flag); paint.setStrokeWidth(1.0f); SkIRect rect; // Bounding rect rect.set(wr.x, wr.y, wr.x + wr.width, wr.y + wr.height); m_webViewHost->canvas()->drawIRect(rect, paint); } } dumpImage(m_webViewHost->canvas()); } m_printer->handleImageFooter(); m_printer->handleTestFooter(dumpedAnything); fflush(stdout); fflush(stderr); }
void onDraw(SkCanvas* canvas) override{ SkPaint blackFill; //----------- // Normal paints (no source) SkTArray<SkPaint> paints; create_paints(nullptr, &paints); //----------- // Paints with a PictureImageFilter as a source SkAutoTUnref<SkPicture> pic; { SkPictureRecorder rec; SkCanvas* c = rec.beginRecording(10, 10); c->drawRect(SkRect::MakeWH(10, 10), blackFill); pic.reset(rec.endRecording()); } SkAutoTUnref<SkPictureImageFilter> pif(SkPictureImageFilter::Create(pic)); SkTArray<SkPaint> pifPaints; create_paints(pif, &pifPaints); //----------- // Paints with a SkImageSource as a source SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterN32Premul(10, 10)); { SkPaint p; SkCanvas* temp = surface->getCanvas(); temp->clear(SK_ColorYELLOW); p.setColor(SK_ColorBLUE); temp->drawRect(SkRect::MakeLTRB(5, 5, 10, 10), p); p.setColor(SK_ColorGREEN); temp->drawRect(SkRect::MakeLTRB(5, 0, 10, 5), p); } SkAutoTUnref<SkImage> image(surface->newImageSnapshot()); SkAutoTUnref<SkImageFilter> imageSource(SkImageSource::Create(image)); SkTArray<SkPaint> bmsPaints; create_paints(imageSource, &bmsPaints); //----------- SkASSERT(paints.count() == kNumVertTiles); SkASSERT(paints.count() == pifPaints.count()); SkASSERT(paints.count() == bmsPaints.count()); // horizontal separators for (int i = 1; i < paints.count(); ++i) { canvas->drawLine(0, i*SkIntToScalar(kTileHeight), SkIntToScalar((SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols)*kTileWidth), i*SkIntToScalar(kTileHeight), blackFill); } // vertical separators for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds) + kNumXtraCols; ++i) { canvas->drawLine(SkIntToScalar(i * kTileWidth), 0, SkIntToScalar(i * kTileWidth), SkIntToScalar(paints.count() * kTileWidth), blackFill); } // A column of saveLayers with PictureImageFilters for (int i = 0; i < pifPaints.count(); ++i) { draw_savelayer_with_paint(SkIPoint::Make(0, i*kTileHeight), canvas, pifPaints[i]); } // A column of saveLayers with BitmapSources for (int i = 0; i < pifPaints.count(); ++i) { draw_savelayer_with_paint(SkIPoint::Make(kTileWidth, i*kTileHeight), canvas, bmsPaints[i]); } // Multiple columns with different geometry for (int i = 0; i < (int)SK_ARRAY_COUNT(gDrawMthds); ++i) { for (int j = 0; j < paints.count(); ++j) { draw_geom_with_paint(*gDrawMthds[i], SkIPoint::Make((i+kNumXtraCols) * kTileWidth, j*kTileHeight), canvas, paints[j]); } } }
virtual void onDrawContent(SkCanvas* canvas) { SkPaint paint; paint.setAntiAlias(true); paint.setStyle(SkPaint::kFill_Style); // Concave test if (1) { SkPath path; canvas->translate(0, 0); path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); path.lineTo(SkIntToScalar(30), SkIntToScalar(30)); path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); canvas->drawPath(path, paint); } // Reverse concave test if (1) { SkPath path; canvas->save(); canvas->translate(100, 0); path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); path.lineTo(SkIntToScalar(30), SkIntToScalar(30)); path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); canvas->drawPath(path, paint); canvas->restore(); } // Bowtie (intersection) if (1) { SkPath path; canvas->save(); canvas->translate(200, 0); path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); canvas->drawPath(path, paint); canvas->restore(); } // "fake" bowtie (concave, but no intersection) if (1) { SkPath path; canvas->save(); canvas->translate(300, 0); path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); path.lineTo(SkIntToScalar(50), SkIntToScalar(40)); path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); path.lineTo(SkIntToScalar(50), SkIntToScalar(60)); path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); canvas->drawPath(path, paint); canvas->restore(); } // Fish test (intersection/concave) if (1) { SkPath path; canvas->save(); canvas->translate(0, 100); path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); path.lineTo(SkIntToScalar(70), SkIntToScalar(50)); path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); path.lineTo(SkIntToScalar(0), SkIntToScalar(50)); canvas->drawPath(path, paint); canvas->restore(); } // Collinear test if (1) { SkPath path; canvas->save(); canvas->translate(100, 100); path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); path.lineTo(SkIntToScalar(50), SkIntToScalar(20)); path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); path.lineTo(SkIntToScalar(50), SkIntToScalar(80)); canvas->drawPath(path, paint); canvas->restore(); } // Hole test if (1) { SkPath path; canvas->save(); canvas->translate(200, 100); path.moveTo(SkIntToScalar(20), SkIntToScalar(20)); path.lineTo(SkIntToScalar(80), SkIntToScalar(20)); path.lineTo(SkIntToScalar(80), SkIntToScalar(80)); path.lineTo(SkIntToScalar(20), SkIntToScalar(80)); path.moveTo(SkIntToScalar(30), SkIntToScalar(30)); path.lineTo(SkIntToScalar(30), SkIntToScalar(70)); path.lineTo(SkIntToScalar(70), SkIntToScalar(70)); path.lineTo(SkIntToScalar(70), SkIntToScalar(30)); canvas->drawPath(path, paint); canvas->restore(); } }
virtual void onDrawContent(SkCanvas* canvas) { SkRect r = { 0, 0, SkIntToScalar(gWidth*2), SkIntToScalar(gHeight*2) }; static const char* gConfigNames[] = { "8888", "565", "4444" }; static const bool gFilters[] = { false, true }; static const char* gFilterNames[] = { "point", "bilinear" }; static const SkShader::TileMode gModes[] = { SkShader::kClamp_TileMode, SkShader::kRepeat_TileMode, SkShader::kMirror_TileMode }; static const char* gModeNames[] = { "C", "R", "M" }; SkScalar y = SkIntToScalar(24); SkScalar x = SkIntToScalar(10); SkCanvas* textCanvas = NULL; if (fTextPicture->width() == 0) { textCanvas = fTextPicture->beginRecording(1000, 1000); } if (textCanvas) { for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) { for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) { SkPaint p; SkString str; p.setAntiAlias(true); p.setDither(true); p.setLooper(&fLooper); str.printf("[%s,%s]", gModeNames[kx], gModeNames[ky]); p.setTextAlign(SkPaint::kCenter_Align); textCanvas->drawText(str.c_str(), str.size(), x + r.width()/2, y, p); x += r.width() * 4 / 3; } } } y += SkIntToScalar(16); for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) { for (size_t j = 0; j < SK_ARRAY_COUNT(gFilters); j++) { x = SkIntToScalar(10); for (size_t kx = 0; kx < SK_ARRAY_COUNT(gModes); kx++) { for (size_t ky = 0; ky < SK_ARRAY_COUNT(gModes); ky++) { SkPaint paint; setup(&paint, fTexture[i], gFilters[j], gModes[kx], gModes[ky]); paint.setDither(true); canvas->save(); canvas->translate(x, y); canvas->drawRect(r, paint); canvas->restore(); x += r.width() * 4 / 3; } } if (textCanvas) { SkPaint p; SkString str; p.setAntiAlias(true); p.setLooper(&fLooper); str.printf("%s, %s", gConfigNames[i], gFilterNames[j]); textCanvas->drawText(str.c_str(), str.size(), x, y + r.height() * 2 / 3, p); } y += r.height() * 4 / 3; } } canvas->drawPicture(*fTextPicture); }
void makePaints() { { // no AA SkPaint p; p.setColor(SK_ColorWHITE); fPaints.push_back(p); } { // AA SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); fPaints.push_back(p); } { // AA with translucent SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); p.setAlpha(0x66); fPaints.push_back(p); } { // AA with mask filter SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); SkMaskFilter* mf = SkBlurMaskFilter::Create( kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)), SkBlurMaskFilter::kHighQuality_BlurFlag); p.setMaskFilter(mf)->unref(); fPaints.push_back(p); } { // AA with radial shader SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); SkPoint center = SkPoint::Make(SkIntToScalar(-5), SkIntToScalar(30)); SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN }; SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 }; SkShader* s = SkGradientShader::CreateRadial(center, SkIntToScalar(20), colors, pos, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode); p.setShader(s)->unref(); fPaints.push_back(p); } { // AA with blur SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); SkBlurDrawLooper* shadowLooper = SkBlurDrawLooper::Create(SK_ColorWHITE, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(10)), SkIntToScalar(5), SkIntToScalar(10), SkBlurDrawLooper::kIgnoreTransform_BlurFlag | SkBlurDrawLooper::kOverrideColor_BlurFlag | SkBlurDrawLooper::kHighQuality_BlurFlag); SkAutoUnref aurL0(shadowLooper); p.setLooper(shadowLooper); fPaints.push_back(p); } { // AA with stroke style SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(SkIntToScalar(3)); fPaints.push_back(p); } { // AA with bevel-stroke style SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); p.setStrokeJoin(SkPaint::kBevel_Join); p.setStrokeWidth(SkIntToScalar(3)); fPaints.push_back(p); } { // AA with round-stroke style SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); p.setStrokeJoin(SkPaint::kRound_Join); p.setStrokeWidth(SkIntToScalar(3)); fPaints.push_back(p); } { // AA with stroke style, width = 0 SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); fPaints.push_back(p); } { // AA with stroke style, width wider than rect width and/or height SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(SkIntToScalar(40)); fPaints.push_back(p); } { // AA with stroke and fill style SkPaint p; p.setColor(SK_ColorWHITE); p.setAntiAlias(true); p.setStyle(SkPaint::kStrokeAndFill_Style); p.setStrokeWidth(SkIntToScalar(2)); fPaints.push_back(p); } }
virtual void onDraw(SkCanvas* canvas) { static const int kBmpSize = 2048; if (fLargeBitmap.isNull()) { makebm(&fLargeBitmap, kBmpSize, kBmpSize); } SkRect dstRect = { 0, 0, SkIntToScalar(64), SkIntToScalar(64)}; static const int kMaxSrcRectSize = 1 << (SkNextLog2(kBmpSize) + 2); static const int kPadX = 30; static const int kPadY = 40; SkPaint paint; paint.setAlpha(0x20); canvas->drawBitmapRect(fLargeBitmap, NULL, SkRect::MakeWH(gSize * SK_Scalar1, gSize * SK_Scalar1), &paint); canvas->translate(SK_Scalar1 * kPadX / 2, SK_Scalar1 * kPadY / 2); SkPaint blackPaint; SkScalar titleHeight = SK_Scalar1 * 24; blackPaint.setColor(SK_ColorBLACK); blackPaint.setTextSize(titleHeight); blackPaint.setAntiAlias(true); SkString title; title.printf("Bitmap size: %d x %d", kBmpSize, kBmpSize); canvas->drawText(title.c_str(), title.size(), 0, titleHeight, blackPaint); canvas->translate(0, SK_Scalar1 * kPadY / 2 + titleHeight); int rowCount = 0; canvas->save(); for (int w = 1; w <= kMaxSrcRectSize; w *= 4) { for (int h = 1; h <= kMaxSrcRectSize; h *= 4) { SkIRect srcRect = SkIRect::MakeXYWH((kBmpSize - w) / 2, (kBmpSize - h) / 2, w, h); canvas->drawBitmapRect(fLargeBitmap, &srcRect, dstRect); SkString label; label.appendf("%d x %d", w, h); blackPaint.setAntiAlias(true); blackPaint.setStyle(SkPaint::kFill_Style); blackPaint.setTextSize(SK_Scalar1 * 10); SkScalar baseline = dstRect.height() + blackPaint.getTextSize() + SK_Scalar1 * 3; canvas->drawText(label.c_str(), label.size(), 0, baseline, blackPaint); blackPaint.setStyle(SkPaint::kStroke_Style); blackPaint.setStrokeWidth(SK_Scalar1); blackPaint.setAntiAlias(false); canvas->drawRect(dstRect, blackPaint); canvas->translate(dstRect.width() + SK_Scalar1 * kPadX, 0); ++rowCount; if ((dstRect.width() + kPadX) * rowCount > gSize) { canvas->restore(); canvas->translate(0, dstRect.height() + SK_Scalar1 * kPadY); canvas->save(); rowCount = 0; } } } { // test the following code path: // SkGpuDevice::drawPath() -> SkGpuDevice::drawWithMaskFilter() SkIRect srcRect; SkPaint paint; SkBitmap bm; bm = make_chessbm(5, 5); paint.setFilterLevel(SkPaint::kLow_FilterLevel); srcRect.setXYWH(1, 1, 3, 3); SkMaskFilter* mf = SkBlurMaskFilter::Create( kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(5)), SkBlurMaskFilter::kHighQuality_BlurFlag | SkBlurMaskFilter::kIgnoreTransform_BlurFlag); paint.setMaskFilter(mf)->unref(); canvas->drawBitmapRect(bm, &srcRect, dstRect, &paint); } }
// Reduce to a single drawBitmapRectToRect call by folding the clipRect's into // the src and dst Rects and the saveLayer paints into the drawBitmapRectToRect's // paint. static void apply_7(SkDebugCanvas* canvas, int curCommand) { SkSaveLayerCommand* saveLayer0 = (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+2); SkSaveLayerCommand* saveLayer1 = (SkSaveLayerCommand*) canvas->getDrawCommandAt(curCommand+5); SkClipRectCommand* clip2 = (SkClipRectCommand*) canvas->getDrawCommandAt(curCommand+7); SkDrawBitmapRectCommand* dbmr = (SkDrawBitmapRectCommand*) canvas->getDrawCommandAt(curCommand+8); SkScalar newSrcLeft = dbmr->srcRect()->fLeft + clip2->rect().fLeft - dbmr->dstRect().fLeft; SkScalar newSrcTop = dbmr->srcRect()->fTop + clip2->rect().fTop - dbmr->dstRect().fTop; SkRect newSrc = SkRect::MakeXYWH(newSrcLeft, newSrcTop, clip2->rect().width(), clip2->rect().height()); dbmr->setSrcRect(newSrc); dbmr->setDstRect(clip2->rect()); SkColor color = 0xFF000000; int a0, a1; const SkPaint* saveLayerPaint0 = saveLayer0->paint(); if (NULL != saveLayerPaint0) { color = saveLayerPaint0->getColor(); a0 = SkColorGetA(color); } else { a0 = 0xFF; } const SkPaint* saveLayerPaint1 = saveLayer1->paint(); if (NULL != saveLayerPaint1) { color = saveLayerPaint1->getColor(); a1 = SkColorGetA(color); } else { a1 = 0xFF; } int newA = SkMulDiv255Round(a0, a1); SkASSERT(newA <= 0xFF); SkPaint* dbmrPaint = dbmr->paint(); if (NULL != dbmrPaint) { SkColor newColor = SkColorSetA(dbmrPaint->getColor(), newA); dbmrPaint->setColor(newColor); } else { SkColor newColor = SkColorSetA(color, newA); SkPaint newPaint; newPaint.setColor(newColor); dbmr->setPaint(newPaint); } // remove everything except the drawbitmaprect canvas->deleteDrawCommandAt(curCommand+13); // restore canvas->deleteDrawCommandAt(curCommand+12); // restore canvas->deleteDrawCommandAt(curCommand+11); // restore canvas->deleteDrawCommandAt(curCommand+10); // restore canvas->deleteDrawCommandAt(curCommand+9); // restore canvas->deleteDrawCommandAt(curCommand+7); // clipRect canvas->deleteDrawCommandAt(curCommand+6); // save canvas->deleteDrawCommandAt(curCommand+5); // saveLayer canvas->deleteDrawCommandAt(curCommand+4); // clipRect canvas->deleteDrawCommandAt(curCommand+3); // save canvas->deleteDrawCommandAt(curCommand+2); // saveLayer canvas->deleteDrawCommandAt(curCommand+1); // clipRect canvas->deleteDrawCommandAt(curCommand); // save }
static SkTypeface::Encoding paint2Encoding(const SkPaint& paint) { SkPaint::TextEncoding enc = paint.getTextEncoding(); SkASSERT(SkPaint::kGlyphID_TextEncoding != enc); return (SkTypeface::Encoding)enc; }