*/
bool cropRectIsSet() const { return fCropRect.flags() != 0x0; }
+ // Default impl returns union of all input bounds.
+ virtual void computeFastBounds(const SkRect&, SkRect*) const;
+
SK_DEFINE_FLATTENABLE_TYPE(SkImageFilter)
protected:
uintptr_t effects = reinterpret_cast<uintptr_t>(this->getLooper());
effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
+ effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
if (!effects) {
return orig;
}
public:
explicit SkBitmapSource(const SkBitmap& bitmap);
SkBitmapSource(const SkBitmap& bitmap, const SkRect& srcRect, const SkRect& dstRect);
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBitmapSource)
SkScalar sigmaY,
SkImageFilter* input = NULL,
const CropRect* cropRect = NULL);
+ virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkBlurImageFilter)
const SkMatrix& ctm,
SkBitmap* dst,
SkIPoint* offset) SK_OVERRIDE;
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
+
#if SK_SUPPORT_GPU
virtual bool canFilterImageGPU() const SK_OVERRIDE { return true; }
virtual bool filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
typedef SkImageFilter INHERITED;
SkImageFilter* getDisplacementInput() { return getInput(0); }
SkImageFilter* getColorInput() { return getInput(1); }
+ const SkImageFilter* getDisplacementInput() const { return getInput(0); }
+ const SkImageFilter* getColorInput() const { return getInput(1); }
};
#endif
public:
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigma, SkColor, SkImageFilter* input = NULL);
SkDropShadowImageFilter(SkScalar dx, SkScalar dy, SkScalar sigmaX, SkScalar sigmaY, SkColor, SkImageFilter* input = NULL, const CropRect* cropRect = NULL);
+ virtual void computeFastBounds(const SkRect&, SkRect*) const SK_OVERRIDE;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDropShadowImageFilter)
protected:
class SK_API SkMorphologyImageFilter : public SkImageFilter {
public:
SkMorphologyImageFilter(int radiusX, int radiusY, SkImageFilter* input, const CropRect* cropRect);
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
/**
* All morphology procs have the same signature: src is the source buffer, dst the
public:
SkOffsetImageFilter(SkScalar dx, SkScalar dy, SkImageFilter* input = NULL,
const CropRect* cropRect = NULL);
+ virtual void computeFastBounds(const SkRect& src, SkRect* dst) const SK_OVERRIDE;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkOffsetImageFilter)
protected:
return this->onFilterBounds(src, ctm, dst);
}
+void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
+ if (0 == fInputCount) {
+ *dst = src;
+ return;
+ }
+ if (this->getInput(0)) {
+ this->getInput(0)->computeFastBounds(src, dst);
+ } else {
+ *dst = src;
+ }
+ for (int i = 1; i < fInputCount; i++) {
+ SkImageFilter* input = this->getInput(i);
+ if (input) {
+ SkRect bounds;
+ input->computeFastBounds(src, &bounds);
+ dst->join(bounds);
+ } else {
+ dst->join(src);
+ }
+ }
+}
+
bool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const SkMatrix&,
SkBitmap*, SkIPoint*) {
return false;
this->getMaskFilter()->computeFastBounds(*storage, storage);
}
+ if (this->getImageFilter()) {
+ this->getImageFilter()->computeFastBounds(*storage, storage);
+ }
+
return *storage;
}
offset->fY = dstIRect.fTop;
return true;
}
+
+void SkBitmapSource::computeFastBounds(const SkRect&, SkRect* dst) const {
+ *dst = fDstRect;
+}
return true;
}
+
+void SkBlurImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
+ if (getInput(0)) {
+ getInput(0)->computeFastBounds(src, dst);
+ } else {
+ *dst = src;
+ }
+
+ dst->outset(SkScalarMul(fSigma.width(), SkIntToScalar(3)),
+ SkScalarMul(fSigma.height(), SkIntToScalar(3)));
+}
bool SkBlurImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const SkMatrix& ctm,
SkBitmap* result, SkIPoint* offset) {
#if SK_SUPPORT_GPU
return true;
}
+void SkDisplacementMapEffect::computeFastBounds(const SkRect& src, SkRect* dst) const {
+ if (getColorInput()) {
+ getColorInput()->computeFastBounds(src, dst);
+ } else {
+ *dst = src;
+ }
+}
+
///////////////////////////////////////////////////////////////////////////////
#if SK_SUPPORT_GPU
offset->fY = bounds.fTop;
return true;
}
+
+void SkDropShadowImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
+ if (getInput(0)) {
+ getInput(0)->computeFastBounds(src, dst);
+ } else {
+ *dst = src;
+ }
+
+ SkRect shadowBounds = *dst;
+ shadowBounds.offset(fDx, fDy);
+ shadowBounds.outset(SkScalarMul(fSigmaX, SkIntToScalar(3)),
+ SkScalarMul(fSigmaY, SkIntToScalar(3)));
+ dst->join(shadowBounds);
+}
+
return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctm, dst, offset);
}
+void SkMorphologyImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
+ if (getInput(0)) {
+ getInput(0)->computeFastBounds(src, dst);
+ } else {
+ *dst = src;
+ }
+ dst->outset(SkIntToScalar(fRadius.width()), SkIntToScalar(fRadius.height()));
+}
+
#if SK_SUPPORT_GPU
///////////////////////////////////////////////////////////////////////////////
return true;
}
+void SkOffsetImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
+ if (getInput(0)) {
+ getInput(0)->computeFastBounds(src, dst);
+ } else {
+ *dst = src;
+ }
+ dst->offset(fOffset.fX, fOffset.fY);
+}
+
bool SkOffsetImageFilter::onFilterBounds(const SkIRect& src, const SkMatrix& ctm,
SkIRect* dst) {
SkVector vec;