• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
OwnDeviceCanvas(SkDevice * device)16     OwnDeviceCanvas(SkDevice* device) : SkCanvas(device) {
17         SkSafeUnref(device);
18     }
19 };
20 
21 ///////////////////////////////////////////////////////////////////////////////
22 
~SkComposeImageFilter()23 SkComposeImageFilter::~SkComposeImageFilter() {
24 }
25 
onFilterImage(Proxy * proxy,const SkBitmap & src,const SkMatrix & ctm,SkBitmap * result,SkIPoint * loc)26 bool SkComposeImageFilter::onFilterImage(Proxy* proxy,
27                                          const SkBitmap& src,
28                                          const SkMatrix& ctm,
29                                          SkBitmap* result,
30                                          SkIPoint* loc) {
31     SkImageFilter* outer = getInput(0);
32     SkImageFilter* inner = getInput(1);
33 
34     if (!outer && !inner) {
35         return false;
36     }
37 
38     if (!outer || !inner) {
39         return (outer ? outer : inner)->filterImage(proxy, src, ctm, result, loc);
40     }
41 
42     SkBitmap tmp;
43     return inner->filterImage(proxy, src, ctm, &tmp, loc) &&
44            outer->filterImage(proxy, tmp, ctm, result, loc);
45 }
46 
onFilterBounds(const SkIRect & src,const SkMatrix & ctm,SkIRect * dst)47 bool SkComposeImageFilter::onFilterBounds(const SkIRect& src,
48                                           const SkMatrix& ctm,
49                                           SkIRect* dst) {
50     SkImageFilter* outer = getInput(0);
51     SkImageFilter* inner = getInput(1);
52 
53     if (!outer && !inner) {
54         return false;
55     }
56 
57     if (!outer || !inner) {
58         return (outer ? outer : inner)->filterBounds(src, ctm, dst);
59     }
60 
61     SkIRect tmp;
62     return inner->filterBounds(src, ctm, &tmp) &&
63            outer->filterBounds(tmp, ctm, dst);
64 }
65 
SkComposeImageFilter(SkFlattenableReadBuffer & buffer)66 SkComposeImageFilter::SkComposeImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
67 }
68 
69 ///////////////////////////////////////////////////////////////////////////////
70 
onFilterImage(Proxy * proxy,const SkBitmap & src,const SkMatrix & matrix,SkBitmap * result,SkIPoint *)71 bool SkDownSampleImageFilter::onFilterImage(Proxy* proxy, const SkBitmap& src,
72                                             const SkMatrix& matrix,
73                                             SkBitmap* result, SkIPoint*) {
74     SkScalar scale = fScale;
75     if (scale > SK_Scalar1 || scale <= 0) {
76         return false;
77     }
78 
79     int dstW = SkScalarRoundToInt(src.width() * scale);
80     int dstH = SkScalarRoundToInt(src.height() * scale);
81     if (dstW < 1) {
82         dstW = 1;
83     }
84     if (dstH < 1) {
85         dstH = 1;
86     }
87 
88     SkBitmap tmp;
89 
90     // downsample
91     {
92         SkDevice* dev = proxy->createDevice(dstW, dstH);
93         if (NULL == dev) {
94             return false;
95         }
96         OwnDeviceCanvas canvas(dev);
97         SkPaint paint;
98 
99         paint.setFilterBitmap(true);
100         canvas.scale(scale, scale);
101         canvas.drawBitmap(src, 0, 0, &paint);
102         tmp = dev->accessBitmap(false);
103     }
104 
105     // upscale
106     {
107         SkDevice* dev = proxy->createDevice(src.width(), src.height());
108         if (NULL == dev) {
109             return false;
110         }
111         OwnDeviceCanvas canvas(dev);
112 
113         SkRect r = SkRect::MakeWH(SkIntToScalar(src.width()),
114                                   SkIntToScalar(src.height()));
115         canvas.drawBitmapRect(tmp, NULL, r, NULL);
116         *result = dev->accessBitmap(false);
117     }
118     return true;
119 }
120 
flatten(SkFlattenableWriteBuffer & buffer) const121 void SkDownSampleImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
122     this->INHERITED::flatten(buffer);
123 
124     buffer.writeScalar(fScale);
125 }
126 
SkDownSampleImageFilter(SkFlattenableReadBuffer & buffer)127 SkDownSampleImageFilter::SkDownSampleImageFilter(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
128     fScale = buffer.readScalar();
129 }
130