Home | History | Annotate | Download | only in effects
      1 
      2 #include "SkTestImageFilters.h"
      3 #include "SkCanvas.h"
      4 #include "SkDevice.h"
      5 #include "SkFlattenableBuffers.h"
      6 
      7 // Simple helper canvas that "takes ownership" of the provided device, so that
      8 // when this canvas goes out of scope, so will its device. Could be replaced
      9 // with the following:
     10 //
     11 //  SkCanvas canvas(device);
     12 //  SkAutoTUnref<SkDevice> aur(device);
     13 //
     14 class OwnDeviceCanvas : public SkCanvas {
     15 public:
     16     OwnDeviceCanvas(SkDevice* device) : SkCanvas(device) {
     17         SkSafeUnref(device);
     18     }
     19 };
     20 
     21 ///////////////////////////////////////////////////////////////////////////////
     22 
     23 bool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
     24                                             const SkMatrix&,
     25                                             SkBitmap* result, SkIPoint*) {
     26     SkScalar scale = fScale;
     27     if (scale > SK_Scalar1 || scale <= 0) {
     28         return false;
     29     }
     30 
     31     int dstW = SkScalarRoundToInt(src.width() * scale);
     32     int dstH = SkScalarRoundToInt(src.height() * scale);
     33     if (dstW < 1) {
     34         dstW = 1;
     35     }
     36     if (dstH < 1) {
     37         dstH = 1;
     38     }
     39 
     40     SkBitmap tmp;
     41 
     42     // downsample
     43     {
     44         SkDevice* dev = proxy->createDevice(dstW, dstH);
     45         if (NULL == dev) {
     46             return false;
     47         }
     48         OwnDeviceCanvas canvas(dev);
     49         SkPaint paint;
     50 
     51         paint.setFilterBitmap(true);
     52         canvas.scale(scale, scale);
     53         canvas.drawBitmap(src, 0, 0, &paint);
     54         tmp = dev->accessBitmap(false);
     55     }
     56 
     57     // upscale
     58     {
     59         SkDevice* dev = proxy->createDevice(src.width(), src.height());
     60         if (NULL == dev) {
     61             return false;
     62         }
     63         OwnDeviceCanvas canvas(dev);
     64 
     65         SkRect r = SkRect::MakeWH(SkIntToScalar(src.width()),
     66                                   SkIntToScalar(src.height()));
     67         canvas.drawBitmapRect(tmp, NULL, r, NULL);
     68         *result = dev->accessBitmap(false);
     69     }
     70     return true;
     71 }
     72 
     73 void SkDownSampleImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
     74     this->INHERITED::flatten(buffer);
     75 
     76     buffer.writeScalar(fScale);
     77 }
     78 
     79 SkDownSampleImageFilter::SkDownSampleImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
     80     fScale = buffer.readScalar();
     81 }
     82