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