void onDraw(SkCanvas* canvas) override { canvas->scale(1.5f, 1.5f); canvas->translate(50,50); const float blurRadii[] = { 1,5,10,20 }; const int cornerRadii[] = { 1,5,10,20 }; const SkRect r = SkRect::MakeWH(SkIntToScalar(25), SkIntToScalar(25)); for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) { SkAutoCanvasRestore autoRestore(canvas, true); canvas->translate(0, (r.height() + SkIntToScalar(50)) * i); for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) { for (int k = 0; k <= 1; k++) { SkMaskFilter* filter = SkBlurMaskFilter::Create( kNormal_SkBlurStyle, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(blurRadii[i])), SkBlurMaskFilter::kHighQuality_BlurFlag); SkPaint paint; paint.setColor(SK_ColorBLACK); paint.setMaskFilter(filter)->unref(); bool useRadial = SkToBool(k); if (useRadial) { paint.setShader(MakeRadial()); } SkRRect rrect; rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]), SkIntToScalar(cornerRadii[j])); canvas->drawRRect(rrect, paint); canvas->translate(r.width() + SkIntToScalar(50), 0); } } } }
bool CopyTilesRenderer::render(SkBitmap** out) { int i = 0; bool success = true; SkBitmap dst; for (int x = 0; x < this->getViewWidth(); x += fLargeTileWidth) { for (int y = 0; y < this->getViewHeight(); y += fLargeTileHeight) { SkAutoCanvasRestore autoRestore(fCanvas, true); // Translate so that we draw the correct portion of the picture. // Perform a postTranslate so that the scaleFactor does not interfere with the // positioning. SkMatrix mat(fCanvas->getTotalMatrix()); mat.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); fCanvas->setMatrix(mat); // Draw the picture fCanvas->drawPicture(*fPicture); // Now extract the picture into tiles const SkBitmap& baseBitmap = fCanvas->getDevice()->accessBitmap(false); SkIRect subset; for (int tileY = 0; tileY < fLargeTileHeight; tileY += this->getTileHeight()) { for (int tileX = 0; tileX < fLargeTileWidth; tileX += this->getTileWidth()) { subset.set(tileX, tileY, tileX + this->getTileWidth(), tileY + this->getTileHeight()); SkDEBUGCODE(bool extracted =) baseBitmap.extractSubset(&dst, subset); SkASSERT(extracted); if (!fOutputDir.isEmpty()) { // Similar to write() in PictureRenderer.cpp, but just encodes // a bitmap directly. // TODO: Share more common code with write() to do this, to properly // write out the JSON summary, etc. SkString pathWithNumber; make_filepath(&pathWithNumber, fOutputDir, fInputFilename); pathWithNumber.remove(pathWithNumber.size() - 4, 4); pathWithNumber.appendf("%i.png", i++); SkBitmap copy; #if SK_SUPPORT_GPU if (isUsingGpuDevice()) { dst.pixelRef()->readPixels(©, &subset); } else { #endif dst.copyTo(©); #if SK_SUPPORT_GPU } #endif success &= SkImageEncoder::EncodeFile(pathWithNumber.c_str(), copy, SkImageEncoder::kPNG_Type, 100); } } } } } return success; }
virtual void onDraw(SkCanvas* canvas) { const int widths[] = {25, 5, 5, 100, 150, 25}; const int heights[] = {100, 100, 5, 25, 150, 25}; const SkBlurStyle styles[] = {kNormal_SkBlurStyle, kInner_SkBlurStyle, kOuter_SkBlurStyle}; const float radii[] = {20, 5, 10}; canvas->translate(50,20); int cur_x = 0; int cur_y = 0; int max_height = 0; for (size_t i = 0 ; i < SK_ARRAY_COUNT(widths) ; i++) { int width = widths[i]; int height = heights[i]; SkRect r; r.setWH(SkIntToScalar(width), SkIntToScalar(height)); SkAutoCanvasRestore autoRestore(canvas, true); for (size_t j = 0 ; j < SK_ARRAY_COUNT(radii) ; j++) { float radius = radii[j]; for (size_t k = 0 ; k < SK_ARRAY_COUNT(styles) ; k++) { SkBlurStyle style = styles[k]; SkMask mask; SkBlurMask::BlurRect(SkBlurMask::ConvertRadiusToSigma(radius), &mask, r, style); SkAutoMaskFreeImage amfi(mask.fImage); SkBitmap bm; bm.installMaskPixels(mask); if (cur_x + bm.width() >= fGMWidth - fMargin) { cur_x = 0; cur_y += max_height + fPadding; max_height = 0; } canvas->save(); canvas->translate((SkScalar)cur_x, (SkScalar)cur_y); canvas->translate(-(bm.width() - r.width())/2, -(bm.height()-r.height())/2); canvas->drawBitmap(bm, 0.f, 0.f, NULL); canvas->restore(); cur_x += bm.width() + fPadding; if (bm.height() > max_height) max_height = bm.height(); } } } }
void draw(SkCanvas* canvas) { SkPaint p; p.setAntiAlias(true); p.setTextSize(64); SkMatrix m; for (SkScalar sx : { -1, 1 } ) { for (SkScalar sy : { -1, 1 } ) { SkAutoCanvasRestore autoRestore(canvas, true); m.setScale(sx, sy); m.postTranslate(128, 64); canvas->concat(m); canvas->drawString("@", 0, 0, p); } } }
void draw(SkCanvas* canvas) { SkMatrix m; m.setIdentity(); m.set(SkMatrix::kMPersp0, -0.004f); SkAutoCanvasRestore autoRestore(canvas, true); canvas->translate(22, 144); SkPaint black; black.setAntiAlias(true); black.setTextSize(24); SkPaint gray = black; gray.setColor(0xFF9f9f9f); SkString string; string.appendScalar(m.getPerspX()); canvas->drawString(string, 0, -72, gray); canvas->concat(m); canvas->drawString(string, 0, 0, black); }
bool CopyTilesRenderer::render(const SkString* path) { int i = 0; bool success = true; SkBitmap dst; for (int x = 0; x < this->getViewWidth(); x += fLargeTileWidth) { for (int y = 0; y < this->getViewHeight(); y += fLargeTileHeight) { SkAutoCanvasRestore autoRestore(fCanvas, true); fCanvas->translate(SkIntToScalar(-x), SkIntToScalar(-y)); // Draw the picture fCanvas->drawPicture(*fPicture); // Now extract the picture into tiles const SkBitmap& baseBitmap = fCanvas->getDevice()->accessBitmap(false); SkIRect subset; for (int tileY = 0; tileY < fLargeTileHeight; tileY += this->getTileHeight()) { for (int tileX = 0; tileX < fLargeTileWidth; tileX += this->getTileWidth()) { subset.set(tileX, tileY, tileX + this->getTileWidth(), tileY + this->getTileHeight()); SkDEBUGCODE(bool extracted =) baseBitmap.extractSubset(&dst, subset); SkASSERT(extracted); if (path != NULL) { // Similar to writeAppendNumber in PictureRenderer.cpp, but just encodes // a bitmap directly. SkString pathWithNumber(*path); pathWithNumber.appendf("%i.png", i++); SkBitmap copy; #if SK_SUPPORT_GPU if (isUsingGpuDevice()) { dst.pixelRef()->readPixels(©, &subset); } else { #endif dst.copyTo(©, dst.config()); #if SK_SUPPORT_GPU } #endif success &= SkImageEncoder::EncodeFile(pathWithNumber.c_str(), copy, SkImageEncoder::kPNG_Type, 100); } } } } } return success; }
void draw(SkCanvas* canvas) { SkPaint p; p.setAntiAlias(true); SkMatrix m; int pos = 0; for (SkScalar sx : { 1, 2 } ) { for (SkScalar kx : { 0, 1 } ) { m.setAll(sx, kx, 16, 0, 1, 32, 0, 0, 1); bool isSimilarity = m.isSimilarity(); bool preservesRightAngles = m.preservesRightAngles(); SkString str; str.printf("sx: %g kx: %g %s %s", sx, kx, isSimilarity ? "sim" : "", preservesRightAngles ? "right" : ""); SkAutoCanvasRestore autoRestore(canvas, true); canvas->concat(m); canvas->drawString(str, 0, pos, p); pos += 20; } } }
void draw(SkCanvas* canvas) { SkPaint black; black.setAntiAlias(true); black.setTextSize(48); SkPaint gray = black; gray.setColor(0xFF9f9f9f); SkScalar offset[] = { 1.5f, 1.5f, 20, 1.5f, 1.5f, 20, .03f, .01f, 2 }; for (int i : { SkMatrix::kMScaleX, SkMatrix::kMSkewX, SkMatrix::kMTransX, SkMatrix::kMSkewY, SkMatrix::kMScaleY, SkMatrix::kMTransY, SkMatrix::kMPersp0, SkMatrix::kMPersp1, SkMatrix::kMPersp2 } ) { SkMatrix m; m.setIdentity(); m.set(i, offset[i]); SkAutoCanvasRestore autoRestore(canvas, true); canvas->translate(22 + (i % 3) * 88, 44 + (i / 3) * 88); canvas->drawString("&", 0, 0, gray); canvas->concat(m); canvas->drawString("&", 0, 0, black); } }
PassOwnPtr<Vector<char>> PictureSnapshot::replay(unsigned fromStep, unsigned toStep, double scale) const { const SkIRect bounds = m_picture->cullRect().roundOut(); // TODO(fmalita): convert this to SkSurface/SkImage, drop the intermediate SkBitmap. SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(bounds.width(), bounds.height())); bitmap.eraseARGB(0, 0, 0, 0); { ReplayingCanvas canvas(bitmap, fromStep, toStep); // Disable LCD text preemptively, because the picture opacity is unknown. // The canonical API involves SkSurface props, but since we're not SkSurface-based // at this point (see TODO above) we (ab)use saveLayer for this purpose. SkAutoCanvasRestore autoRestore(&canvas, false); canvas.saveLayer(nullptr, nullptr); canvas.scale(scale, scale); canvas.resetStepCount(); m_picture->playback(&canvas, &canvas); } OwnPtr<Vector<char>> base64Data = adoptPtr(new Vector<char>()); Vector<char> encodedImage; RefPtr<SkImage> image = adoptRef(SkImage::NewFromBitmap(bitmap)); if (!image) return nullptr; ImagePixelLocker pixelLocker(image, kUnpremul_SkAlphaType, kRGBA_8888_SkColorType); ImageDataBuffer imageData(IntSize(image->width(), image->height()), static_cast<const unsigned char*>(pixelLocker.pixels())); if (!PNGImageEncoder::encode(imageData, reinterpret_cast<Vector<unsigned char>*>(&encodedImage))) return nullptr; base64Encode(encodedImage, *base64Data); return base64Data.release(); }