SkIRect SkComposeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, MapDirection direction) const { SkImageFilter* outer = this->getInput(0); SkImageFilter* inner = this->getInput(1); return outer->filterBounds(inner->filterBounds(src, ctm, direction), ctm, direction); }
bool SkComposeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const { SkImageFilter* outer = getInput(0); SkImageFilter* inner = getInput(1); SkIRect tmp; return inner->filterBounds(src, ctm, &tmp) && outer->filterBounds(tmp, ctm, dst); }
bool SkMergeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) { if (fCount < 1) { return false; } SkIRect totalBounds; for (int i = 0; i < fCount; ++i) { SkImageFilter* filter = fFilters[i]; SkIRect r; if (filter) { if (!filter->filterBounds(src, ctm, &r)) { return false; } } else { r = src; } if (0 == i) { totalBounds = r; } else { totalBounds.join(r); } } // don't modify dst until now, so we don't accidentally change it in the // loop, but then return false on the next filter. *dst = totalBounds; return true; }
bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst, MapDirection direction) const { if (fInputCount < 1) { *dst = src; return true; } SkIRect totalBounds; for (int i = 0; i < fInputCount; ++i) { SkImageFilter* filter = this->getInput(i); SkIRect rect = src; if (filter && !filter->filterBounds(src, ctm, &rect, direction)) { return false; } if (0 == i) { totalBounds = rect; } else { totalBounds.join(rect); } } // don't modify dst until now, so we don't accidentally change it in the // loop, but then return false on the next filter. *dst = totalBounds; return true; }
bool SkComposeImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) { SkImageFilter* outer = getInput(0); SkImageFilter* inner = getInput(1); if (!outer && !inner) { return false; } if (!outer || !inner) { return (outer ? outer : inner)->filterBounds(src, ctm, dst); } SkIRect tmp; return inner->filterBounds(src, ctm, &tmp) && outer->filterBounds(tmp, ctm, dst); }
SkIRect SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, MapDirection direction) const { if (this->countInputs() < 1) { return src; } SkIRect totalBounds; for (int i = 0; i < this->countInputs(); ++i) { SkImageFilter* filter = this->getInput(i); SkIRect rect = filter ? filter->filterBounds(src, ctm, direction) : src; if (0 == i) { totalBounds = rect; } else { totalBounds.join(rect); } } return totalBounds; }
bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src, SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const { SkIRect srcBounds; src.getBounds(&srcBounds); srcBounds.offset(*srcOffset); #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS if (!fCropRect.applyTo(srcBounds, ctx, bounds)) { #else SkIRect dstBounds; this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirection); if (!fCropRect.applyTo(dstBounds, ctx, bounds)) { #endif return false; } if (srcBounds.contains(*bounds)) { *dst = src; return true; } else { SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), bounds->height())); if (!device) { return false; } SkCanvas canvas(device); canvas.clear(0x00000000); canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y()); *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); *dst = device->accessBitmap(false); return true; } } bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const { if (fInputCount < 1) { *dst = src; return true; } SkIRect bounds, totalBounds; this->onFilterNodeBounds(src, ctm, &bounds, kReverse_MapDirection); for (int i = 0; i < fInputCount; ++i) { SkImageFilter* filter = this->getInput(i); SkIRect rect = bounds; if (filter && !filter->filterBounds(bounds, ctm, &rect)) { return false; } if (0 == i) { totalBounds = rect; } else { totalBounds.join(rect); } } // don't modify dst until now, so we don't accidentally change it in the // loop, but then return false on the next filter. *dst = totalBounds; return true; } void SkImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst, MapDirection) const { *dst = src; } SkImageFilter::Context SkImageFilter::mapContext(const Context& ctx) const { #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS return ctx; #else SkIRect clipBounds; this->onFilterNodeBounds(ctx.clipBounds(), ctx.ctm(), &clipBounds, MapDirection::kReverse_MapDirection); return Context(ctx.ctm(), clipBounds, ctx.cache()); #endif } bool SkImageFilter::asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&, const SkIRect&) const { return false; } SkImageFilter* SkImageFilter::CreateMatrixFilter(const SkMatrix& matrix, SkFilterQuality filterQuality, SkImageFilter* input) { return SkMatrixImageFilter::Create(matrix, filterQuality, input); } SkImageFilter* SkImageFilter::newWithLocalMatrix(const SkMatrix& matrix) const { // SkLocalMatrixImageFilter takes SkImage* in its factory, but logically that parameter // is *always* treated as a const ptr. Hence the const-cast here. // return SkLocalMatrixImageFilter::Create(matrix, const_cast<SkImageFilter*>(this)); } #if SK_SUPPORT_GPU bool SkImageFilter::filterInputGPU(int index, SkImageFilter::Proxy* proxy, const SkBitmap& src, const Context& ctx, SkBitmap* result, SkIPoint* offset) const { SkImageFilter* input = this->getInput(index); if (!input) { return true; } // Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity // matrix with no clip and that the matrix, clip, and render target set before this function was // called are restored before we return to the caller. GrContext* context = src.getTexture()->getContext(); if (input->filterImage(proxy, src, this->mapContext(ctx), result, offset)) { if (!result->getTexture()) { const SkImageInfo info = result->info(); if (kUnknown_SkColorType == info.colorType()) { return false; } SkAutoTUnref<GrTexture> resultTex( GrRefCachedBitmapTexture(context, *result, GrTextureParams::ClampNoFilter())); if (!resultTex) { return false; } result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref(); } return true; } else { return false; } }
bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src, SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const { SkIRect srcBounds; src.getBounds(&srcBounds); srcBounds.offset(*srcOffset); #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS if (!fCropRect.applyTo(srcBounds, ctx, bounds)) { #else SkIRect dstBounds; this->onFilterNodeBounds(srcBounds, ctx.ctm(), &dstBounds, kForward_MapDirection); if (!fCropRect.applyTo(dstBounds, ctx, bounds)) { #endif return false; } if (srcBounds.contains(*bounds)) { *dst = src; return true; } else { SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), bounds->height())); if (!device) { return false; } SkCanvas canvas(device); canvas.clear(0x00000000); canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y()); *srcOffset = SkIPoint::Make(bounds->x(), bounds->y()); *dst = device->accessBitmap(false); return true; } } bool SkImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst) const { if (fInputCount < 1) { *dst = src; return true; } SkIRect bounds, totalBounds; this->onFilterNodeBounds(src, ctm, &bounds, kReverse_MapDirection); for (int i = 0; i < fInputCount; ++i) { SkImageFilter* filter = this->getInput(i); SkIRect rect = bounds; if (filter && !filter->filterBounds(bounds, ctm, &rect)) { return false; } if (0 == i) { totalBounds = rect; } else { totalBounds.join(rect); } } // don't modify dst until now, so we don't accidentally change it in the // loop, but then return false on the next filter. *dst = totalBounds; return true; } void SkImageFilter::onFilterNodeBounds(const SkIRect& src, const SkMatrix&, SkIRect* dst, MapDirection) const { *dst = src; } SkImageFilter::Context SkImageFilter::mapContext(const Context& ctx) const { #ifdef SK_SUPPORT_SRC_BOUNDS_BLOAT_FOR_IMAGEFILTERS return ctx; #else SkIRect clipBounds; this->onFilterNodeBounds(ctx.clipBounds(), ctx.ctm(), &clipBounds, MapDirection::kReverse_MapDirection); return Context(ctx.ctm(), clipBounds, ctx.cache(), ctx.sizeConstraint()); #endif } bool SkImageFilter::asFragmentProcessor(GrFragmentProcessor**, GrTexture*, const SkMatrix&, const SkIRect&) const { return false; } SkImageFilter* SkImageFilter::CreateMatrixFilter(const SkMatrix& matrix, SkFilterQuality filterQuality, SkImageFilter* input) { return SkMatrixImageFilter::Create(matrix, filterQuality, input); } SkImageFilter* SkImageFilter::newWithLocalMatrix(const SkMatrix& matrix) const { // SkLocalMatrixImageFilter takes SkImage* in its factory, but logically that parameter // is *always* treated as a const ptr. Hence the const-cast here. // return SkLocalMatrixImageFilter::Create(matrix, const_cast<SkImageFilter*>(this)); } #if SK_SUPPORT_GPU void SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) { SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); result->setInfo(info); result->setPixelRef(new SkGrPixelRef(info, texture))->unref(); }