ca28dd11195e63e7fca7641fee18062314a09b42
[platform/upstream/libSkiaSharp.git] / gm / image.cpp
1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7
8 #include "gm.h"
9 #include "SkData.h"
10 #include "SkCanvas.h"
11 #include "SkRandom.h"
12 #include "SkStream.h"
13 #include "SkSurface.h"
14
15 #if SK_SUPPORT_GPU
16 #include "GrContext.h"
17 #endif
18
19 static void drawJpeg(SkCanvas* canvas, const SkISize& size) {
20     // TODO: Make this draw a file that is checked in, so it can
21     // be exercised on machines other than mike's. Will require a
22     // rebaseline.
23     SkAutoDataUnref data(SkData::NewFromFileName("/Users/mike/Downloads/skia.google.jpeg"));
24     if (NULL == data.get()) {
25         return;
26     }
27     SkImage* image = SkImage::NewFromData(data);
28     if (image) {
29         SkAutoCanvasRestore acr(canvas, true);
30         canvas->scale(size.width() * 1.0f / image->width(),
31                       size.height() * 1.0f / image->height());
32         canvas->drawImage(image, 0, 0, NULL);
33         image->unref();
34     }
35 }
36
37 static void drawContents(SkSurface* surface, SkColor fillC) {
38     SkSize size = SkSize::Make(SkIntToScalar(surface->width()),
39                                SkIntToScalar(surface->height()));
40     SkCanvas* canvas = surface->getCanvas();
41
42     SkScalar stroke = size.fWidth / 10;
43     SkScalar radius = (size.fWidth - stroke) / 2;
44
45     SkPaint paint;
46
47     paint.setAntiAlias(true);
48     paint.setColor(fillC);
49     canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);
50
51     paint.setStyle(SkPaint::kStroke_Style);
52     paint.setStrokeWidth(stroke);
53     paint.setColor(SK_ColorBLACK);
54     canvas->drawCircle(size.fWidth/2, size.fHeight/2, radius, paint);
55 }
56
57 static void test_surface(SkCanvas* canvas, SkSurface* surf, bool usePaint) {
58     drawContents(surf, SK_ColorRED);
59     SkImage* imgR = surf->newImageSnapshot();
60
61     if (true) {
62         SkImage* imgR2 = surf->newImageSnapshot();
63         SkASSERT(imgR == imgR2);
64         imgR2->unref();
65     }
66
67     drawContents(surf, SK_ColorGREEN);
68     SkImage* imgG = surf->newImageSnapshot();
69
70     // since we've drawn after we snapped imgR, imgG will be a different obj
71     SkASSERT(imgR != imgG);
72
73     drawContents(surf, SK_ColorBLUE);
74
75     SkPaint paint;
76 //    paint.setFilterBitmap(true);
77 //    paint.setAlpha(0x80);
78
79     canvas->drawImage(imgR, 0, 0, usePaint ? &paint : NULL);
80     canvas->drawImage(imgG, 0, 80, usePaint ? &paint : NULL);
81     surf->draw(canvas, 0, 160, usePaint ? &paint : NULL);
82
83     SkRect src1, src2, src3;
84     src1.iset(0, 0, surf->width(), surf->height());
85     src2.iset(-surf->width() / 2, -surf->height() / 2,
86              surf->width(), surf->height());
87     src3.iset(0, 0, surf->width() / 2, surf->height() / 2);
88
89     SkRect dst1, dst2, dst3, dst4;
90     dst1.set(0, 240, 65, 305);
91     dst2.set(0, 320, 65, 385);
92     dst3.set(0, 400, 65, 465);
93     dst4.set(0, 480, 65, 545);
94
95     canvas->drawImageRect(imgR, &src1, dst1, usePaint ? &paint : NULL);
96     canvas->drawImageRect(imgG, &src2, dst2, usePaint ? &paint : NULL);
97     canvas->drawImageRect(imgR, &src3, dst3, usePaint ? &paint : NULL);
98     canvas->drawImageRect(imgG, NULL, dst4, usePaint ? &paint : NULL);
99
100     imgG->unref();
101     imgR->unref();
102 }
103
104 class ImageGM : public skiagm::GM {
105     void*   fBuffer;
106     size_t  fBufferSize;
107     SkSize  fSize;
108     enum {
109         W = 64,
110         H = 64,
111         RB = W * 4 + 8,
112     };
113 public:
114     ImageGM() {
115         fBufferSize = RB * H;
116         fBuffer = sk_malloc_throw(fBufferSize);
117         fSize.set(SkIntToScalar(W), SkIntToScalar(H));
118     }
119
120     virtual ~ImageGM() {
121         sk_free(fBuffer);
122     }
123
124 protected:
125     SkString onShortName() SK_OVERRIDE {
126         return SkString("image-surface");
127     }
128
129     SkISize onISize() SK_OVERRIDE {
130         return SkISize::Make(960, 1200);
131     }
132
133     void onDraw(SkCanvas* canvas) SK_OVERRIDE {
134         drawJpeg(canvas, this->getISize());
135
136         canvas->scale(2, 2);
137
138         static const char* kLabel1 = "Original Img";
139         static const char* kLabel2 = "Modified Img";
140         static const char* kLabel3 = "Cur Surface";
141         static const char* kLabel4 = "Full Crop";
142         static const char* kLabel5 = "Over-crop";
143         static const char* kLabel6 = "Upper-left";
144         static const char* kLabel7 = "No Crop";
145
146         static const char* kLabel8 = "Pre-Alloc Img";
147         static const char* kLabel9 = "New Alloc Img";
148         static const char* kLabel10 = "GPU";
149
150         SkPaint textPaint;
151         textPaint.setAntiAlias(true);
152         sk_tool_utils::set_portable_typeface(&textPaint);
153         textPaint.setTextSize(8);
154
155         canvas->drawText(kLabel1, strlen(kLabel1), 10,  60, textPaint);
156         canvas->drawText(kLabel2, strlen(kLabel2), 10, 140, textPaint);
157         canvas->drawText(kLabel3, strlen(kLabel3), 10, 220, textPaint);
158         canvas->drawText(kLabel4, strlen(kLabel4), 10, 300, textPaint);
159         canvas->drawText(kLabel5, strlen(kLabel5), 10, 380, textPaint);
160         canvas->drawText(kLabel6, strlen(kLabel6), 10, 460, textPaint);
161         canvas->drawText(kLabel7, strlen(kLabel7), 10, 540, textPaint);
162
163         canvas->drawText(kLabel8, strlen(kLabel8),  80, 10, textPaint);
164         canvas->drawText(kLabel9, strlen(kLabel9), 160, 10, textPaint);
165         canvas->drawText(kLabel10, strlen(kLabel10), 265, 10, textPaint);
166
167         canvas->translate(80, 20);
168
169         // since we draw into this directly, we need to start fresh
170         sk_bzero(fBuffer, fBufferSize);
171
172         SkImageInfo info = SkImageInfo::MakeN32Premul(W, H);
173         SkAutoTUnref<SkSurface> surf0(SkSurface::NewRasterDirect(info, fBuffer, RB));
174         SkAutoTUnref<SkSurface> surf1(SkSurface::NewRaster(info));
175         SkAutoTUnref<SkSurface> surf2;  // gpu
176
177 #if SK_SUPPORT_GPU
178         surf2.reset(SkSurface::NewRenderTarget(canvas->getGrContext(),
179                                                SkSurface::kNo_Budgeted, info));
180 #endif
181
182         test_surface(canvas, surf0, true);
183         canvas->translate(80, 0);
184         test_surface(canvas, surf1, true);
185         if (surf2) {
186             canvas->translate(80, 0);
187             test_surface(canvas, surf2, true);
188         }
189     }
190
191 private:
192     typedef skiagm::GM INHERITED;
193 };
194 DEF_GM( return new ImageGM; )
195
196 class ImageResizeGM : public skiagm::GM {
197     enum {
198         W = 100,
199         H = 100,
200     };
201 public:
202     ImageResizeGM() {}
203
204 protected:
205     SkString onShortName() SK_OVERRIDE { return SkString("image-resize"); }
206
207     SkISize onISize() SK_OVERRIDE { return SkISize::Make(510, 480); }
208
209     void drawIntoImage(SkCanvas* canvas) {
210         SkPaint paint;
211         paint.setAntiAlias(true);
212         paint.setStyle(SkPaint::kStroke_Style);
213         paint.setStrokeWidth(3);
214         SkRandom rand;
215         for (int i = 0; i < 60; ++i) {
216             paint.setColor(rand.nextU());
217             SkScalar x = rand.nextUScalar1() * W;
218             SkScalar y = rand.nextUScalar1() * H;
219             SkScalar r = rand.nextUScalar1() * W / 2;
220             canvas->drawCircle(x, y, r, paint);
221         }
222     }
223
224     SkImage* makeImage(SkCanvas* canvas) {
225         const SkImageInfo info = SkImageInfo::MakeN32Premul(W, H);
226         SkAutoTUnref<SkSurface> surface(canvas->newSurface(info));
227         if (!surface) {
228             surface.reset(SkSurface::NewRaster(info));
229         }
230         this->drawIntoImage(surface->getCanvas());
231         return surface->newImageSnapshot();
232     }
233
234     void drawResized(SkCanvas* canvas, SkImage* image, int newW, int newH, const SkIRect* subset,
235                      SkFilterQuality fq) {
236         // canvas method
237         SkPaint paint;
238         paint.setFilterQuality(fq);
239         SkRect dstR = SkRect::MakeWH(SkIntToScalar(newW), SkIntToScalar(newH));
240         SkRect srcR;
241         if (subset) {
242             srcR.set(*subset);
243         }
244         canvas->drawImageRect(image, subset ? &srcR : NULL, dstR, &paint);
245         canvas->translate(newW + 20.0f, 0);
246
247         // image method
248         SkAutoTUnref<SkImage> image2(image->newImage(newW, newH, subset, fq));
249         canvas->drawImage(image2, 0, 0, NULL);
250         canvas->translate(image2->width() + 20.0f, 0);
251     }
252
253     void drawImage(SkCanvas* canvas, SkImage* image, SkFilterQuality fq) {
254
255         canvas->drawImage(image, 0, 0, NULL);
256         canvas->translate(image->width() + 20.0f, 0);
257         this->drawResized(canvas, image, image->width()*4/10, image->height()*4/10, NULL, fq);
258
259         SkIRect subset = SkIRect::MakeLTRB(W/4, H/4, W/2, H/2);
260         this->drawResized(canvas, image, W, H, &subset, fq);
261     }
262
263     void onDraw(SkCanvas* canvas) SK_OVERRIDE {
264         canvas->translate(10, 10);
265
266         SkAutoTUnref<SkImage> image(this->makeImage(canvas));
267
268         const SkFilterQuality fq[] = {
269             kNone_SkFilterQuality,
270             kLow_SkFilterQuality,
271             kMedium_SkFilterQuality,
272             kHigh_SkFilterQuality,
273         };
274         for (size_t i = 0; i < SK_ARRAY_COUNT(fq); ++i) {
275             {
276                 SkAutoCanvasRestore acr(canvas, true);
277                 this->drawImage(canvas, image, fq[i]);
278             }
279             canvas->translate(0, image->height() + 20.0f);
280         }
281     }
282     
283 private:
284     typedef skiagm::GM INHERITED;
285 };
286 DEF_GM( return new ImageResizeGM; )
287