Working plumb of image scaling:
[platform/upstream/libSkiaSharp.git] / gm / downsamplebitmap.cpp
1 /*
2  * Copyright 2013 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 "SkGradientShader.h"
10
11 #include "SkTypeface.h"
12 #include "SkImageDecoder.h"
13 #include "SkStream.h"
14
15 static void setTypeface(SkPaint* paint, const char name[], SkTypeface::Style style) {
16     SkSafeUnref(paint->setTypeface(SkTypeface::CreateFromName(name, style)));
17 }
18
19 class DownsampleBitmapGM : public skiagm::GM {
20
21 public:
22     SkBitmap    fBM;
23     SkString    fName;
24     bool        fBitmapMade;
25     
26     DownsampleBitmapGM()
27     {
28         this->setBGColor(0xFFDDDDDD);
29         fBitmapMade = false;
30     }
31
32     void setName(const char name[]) {
33         fName.set(name);
34     }
35
36 protected:
37     virtual SkString onShortName() SK_OVERRIDE {
38         return fName;
39     }
40
41     virtual SkISize onISize() SK_OVERRIDE {
42         make_bitmap_wrapper();
43         return SkISize::Make(4 * fBM.width(), fBM.height());
44     }
45     
46     void make_bitmap_wrapper() {
47         if (!fBitmapMade) {
48             fBitmapMade = true;
49             make_bitmap();
50         }
51     }
52
53     virtual void make_bitmap() = 0;
54
55     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
56         make_bitmap_wrapper();
57         
58         int curX = 0;
59         int curWidth;
60         float curScale = 1;
61         do {
62             
63             SkMatrix matrix;
64             matrix.setScale( curScale, curScale );
65             
66             SkPaint paint;
67             paint.setFilterBitmap(true);
68             paint.setFlags( paint.getFlags() | SkPaint::kHighQualityFilterBitmap_Flag );
69
70             canvas->save();
71             canvas->translate( curX, 0 );
72             canvas->drawBitmapMatrix( fBM, matrix, &paint );
73             canvas->restore();
74             
75             curWidth = (int) (fBM.width() * curScale + 2);
76             curX += curWidth;
77             curScale *= 0.75;
78         } while (curX < 4*fBM.width());
79     }
80
81 private:
82     typedef skiagm::GM INHERITED;
83 };
84
85 class DownsampleBitmapTextGM: public DownsampleBitmapGM {
86   public:
87       DownsampleBitmapTextGM(float textSize)
88       : fTextSize(textSize)
89         {
90             char name[1024];
91             sprintf(name, "downsamplebitmap_text_%.2fpt", fTextSize);
92             setName(name);
93         }
94
95   protected:
96       float fTextSize;
97
98       virtual void make_bitmap() SK_OVERRIDE {
99           fBM.setConfig(SkBitmap::kARGB_8888_Config, int(fTextSize * 8), int(fTextSize * 6));
100           fBM.allocPixels();
101           SkCanvas canvas(fBM);
102           canvas.drawColor(SK_ColorWHITE);
103
104           SkPaint paint;
105           paint.setAntiAlias(true);
106           paint.setSubpixelText(true);
107           paint.setTextSize(fTextSize);
108
109           setTypeface(&paint, "Times", SkTypeface::kNormal);
110           canvas.drawText("Hamburgefons", 12, fTextSize/2, 1.2f*fTextSize, paint);
111           setTypeface(&paint, "Times", SkTypeface::kBold);
112           canvas.drawText("Hamburgefons", 12, fTextSize/2, 2.4f*fTextSize, paint);
113           setTypeface(&paint, "Times", SkTypeface::kItalic);
114           canvas.drawText("Hamburgefons", 12, fTextSize/2, 3.6f*fTextSize, paint);
115           setTypeface(&paint, "Times", SkTypeface::kBoldItalic);
116           canvas.drawText("Hamburgefons", 12, fTextSize/2, 4.8f*fTextSize, paint);
117       }
118   private:
119       typedef DownsampleBitmapGM INHERITED;
120 };
121
122 class DownsampleBitmapCheckerboardGM: public DownsampleBitmapGM {
123   public:
124       DownsampleBitmapCheckerboardGM(int size, int numChecks)
125       : fSize(size), fNumChecks(numChecks)
126         {
127             char name[1024];
128             sprintf(name, "downsamplebitmap_checkerboard_%d_%d", fSize, fNumChecks);
129             setName(name);
130         }
131
132   protected:
133       int fSize;
134       int fNumChecks;
135
136       virtual void make_bitmap() SK_OVERRIDE {
137           fBM.setConfig(SkBitmap::kARGB_8888_Config, fSize, fSize);
138           fBM.allocPixels();
139           SkAutoLockPixels lock(fBM);
140           for (int y = 0; y < fSize; ++y) {
141               for (int x = 0; x < fSize; ++x) {
142                   SkPMColor* s = fBM.getAddr32(x, y);
143                   int cx = (x * fNumChecks) / fSize;
144                   int cy = (y * fNumChecks) / fSize;
145                   if ((cx+cy)%2) {
146                       *s = 0xFFFFFFFF;
147                   } else {
148                       *s = 0xFF000000;
149                   }
150               }
151           }
152       }
153   private:
154       typedef DownsampleBitmapGM INHERITED;
155 };
156
157 class DownsampleBitmapImageGM: public DownsampleBitmapGM {
158   public:
159       DownsampleBitmapImageGM(const char filename[])
160       : fFilename(filename)
161         {
162             char name[1024];
163             sprintf(name, "downsamplebitmap_image_%s", filename);
164             setName(name);
165         }
166
167   protected:
168       SkString fFilename;
169       int fSize;
170
171       virtual void make_bitmap() SK_OVERRIDE {
172           SkString path(skiagm::GM::gResourcePath);
173           path.append("/");
174           path.append(fFilename);
175
176           SkImageDecoder *codec = NULL;
177           SkFILEStream stream(path.c_str());
178           if (stream.isValid()) {
179               codec = SkImageDecoder::Factory(&stream);
180           }
181           if (codec) {
182               stream.rewind();
183               codec->decode(&stream, &fBM, SkBitmap::kARGB_8888_Config,
184                   SkImageDecoder::kDecodePixels_Mode);
185               SkDELETE(codec);
186           } else {
187               fBM.setConfig(SkBitmap::kARGB_8888_Config, 1, 1);
188               fBM.allocPixels();
189               *(fBM.getAddr32(0,0)) = 0xFF0000FF; // red == bad
190           }
191           fSize = fBM.height();
192       }
193   private:
194       typedef DownsampleBitmapGM INHERITED;
195 };
196
197 //////////////////////////////////////////////////////////////////////////////
198
199 DEF_GM( return new DownsampleBitmapTextGM(72); )
200 DEF_GM( return new DownsampleBitmapCheckerboardGM(512,256); )
201 DEF_GM( return new DownsampleBitmapImageGM("mandrill_512.png"); )