void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y, const SkPaint& paint) { SkASSERT(!srcImg->isTextureBacked()); SkBitmap resultBM; SkImageFilter* filter = paint.getImageFilter(); if (filter) { SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix = *draw.fMatrix; matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y); SkAutoTUnref<SkImageFilterCache> cache(this->getImageFilterCache()); SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace()); SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties); sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset)); if (resultImg) { SkPaint tmpUnfiltered(paint); tmpUnfiltered.setImageFilter(nullptr); if (resultImg->getROPixels(&resultBM)) { this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered); } } } else { if (srcImg->getROPixels(&resultBM)) { this->drawSprite(draw, resultBM, x, y, paint); } } }
void SkBaseDevice::drawSpriteWithFilter(const SkDraw& draw, const SkBitmap& bitmap, int x, int y, const SkPaint& paint) { SkImageFilter* filter = paint.getImageFilter(); SkASSERT(filter); SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix = *draw.fMatrix; matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y); SkAutoTUnref<SkImageFilterCache> cache(this->getImageFilterCache()); SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); sk_sp<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(bitmap, &this->surfaceProps())); if (!srcImg) { return; // something disastrous happened } sk_sp<SkSpecialImage> resultImg(filter->filterImage(srcImg.get(), ctx, &offset)); if (resultImg) { SkPaint tmpUnfiltered(paint); tmpUnfiltered.setImageFilter(nullptr); SkBitmap resultBM; if (resultImg->internal_getBM(&resultBM)) { // TODO: add drawSprite(SkSpecialImage) to SkDevice? (see skbug.com/5073) this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered); } } }
void SkBaseDevice::drawBitmapAsSprite(const SkDraw& draw, const SkBitmap& bitmap, int x, int y, const SkPaint& paint) { SkImageFilter* filter = paint.getImageFilter(); if (filter && !this->canHandleImageFilter(filter)) { SkImageFilter::DeviceProxy proxy(this); SkBitmap dst; SkIPoint offset = SkIPoint::Make(0, 0); SkMatrix matrix = *draw.fMatrix; matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y)); const SkIRect clipBounds = draw.fClip->getBounds().makeOffset(-x, -y); SkAutoTUnref<SkImageFilter::Cache> cache(this->getImageFilterCache()); SkImageFilter::Context ctx(matrix, clipBounds, cache.get()); if (filter->filterImageDeprecated(&proxy, bitmap, ctx, &dst, &offset)) { SkPaint tmpUnfiltered(paint); tmpUnfiltered.setImageFilter(nullptr); this->drawSprite(draw, dst, x + offset.x(), y + offset.y(), tmpUnfiltered); } } else { this->drawSprite(draw, bitmap, x, y, paint); } }