bitmaprect.cpp revision 80bacfeb4bda06541e8695bd502229727bccfeab
1
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8#include "gm.h"
9#include "SkCanvas.h"
10#include "SkGradientShader.h"
11#include "SkGraphics.h"
12#include "SkPath.h"
13#include "SkRegion.h"
14#include "SkShader.h"
15
16static void make_bitmap(SkBitmap* bitmap) {
17    bitmap->setConfig(SkBitmap::kARGB_8888_Config, 64, 64);
18    bitmap->allocPixels();
19
20    SkCanvas canvas(*bitmap);
21
22    canvas.drawColor(SK_ColorRED);
23    SkPaint paint;
24    paint.setAntiAlias(true);
25    const SkPoint pts[] = { { 0, 0 }, { 64, 64 } };
26    const SkColor colors[] = { SK_ColorWHITE, SK_ColorBLUE };
27    paint.setShader(SkGradientShader::CreateLinear(pts, colors, NULL, 2,
28                                                   SkShader::kClamp_TileMode))->unref();
29    canvas.drawCircle(32, 32, 32, paint);
30}
31
32class DrawBitmapRect2 : public skiagm::GM {
33    bool fUseIRect;
34public:
35    DrawBitmapRect2(bool useIRect) : fUseIRect(useIRect) {
36    }
37
38protected:
39    virtual SkString onShortName() SK_OVERRIDE {
40        SkString str;
41        str.printf("bitmaprect_%s", fUseIRect ? "i" : "s");
42        return str;
43    }
44
45    virtual SkISize onISize() SK_OVERRIDE {
46        return SkISize::Make(640, 480);
47    }
48
49    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
50        canvas->drawColor(0xFFCCCCCC);
51
52        const SkIRect src[] = {
53            { 0, 0, 32, 32 },
54            { 0, 0, 80, 80 },
55            { 32, 32, 96, 96 },
56            { -32, -32, 32, 32, }
57        };
58
59        SkPaint paint;
60        paint.setStyle(SkPaint::kStroke_Style);
61
62        SkBitmap bitmap;
63        make_bitmap(&bitmap);
64
65        SkRect dstR = { 0, 200, 128, 380 };
66
67        canvas->translate(16, 40);
68        for (size_t i = 0; i < SK_ARRAY_COUNT(src); i++) {
69            SkRect srcR;
70            srcR.set(src[i]);
71
72            canvas->drawBitmap(bitmap, 0, 0, &paint);
73            if (!fUseIRect) {
74                canvas->drawBitmapRectToRect(bitmap, &srcR, dstR, &paint);
75            } else {
76                canvas->drawBitmapRect(bitmap, &src[i], dstR, &paint);
77            }
78
79            canvas->drawRect(dstR, paint);
80            canvas->drawRect(srcR, paint);
81
82            canvas->translate(160, 0);
83        }
84    }
85
86private:
87    typedef skiagm::GM INHERITED;
88};
89
90//////////////////////////////////////////////////////////////////////////////
91static void make_3x3_bitmap(SkBitmap* bitmap) {
92
93    static const int gXSize = 3;
94    static const int gYSize = 3;
95
96    SkColor textureData[gXSize][gYSize] = {
97        SK_ColorRED,    SK_ColorWHITE, SK_ColorBLUE,
98        SK_ColorGREEN,  SK_ColorBLACK, SK_ColorCYAN,
99        SK_ColorYELLOW, SK_ColorGRAY,  SK_ColorMAGENTA
100    };
101
102
103    bitmap->setConfig(SkBitmap::kARGB_8888_Config, gXSize, gYSize);
104    bitmap->allocPixels();
105
106    SkAutoLockPixels lock(*bitmap);
107    for (int y = 0; y < gYSize; y++) {
108        for (int x = 0; x < gXSize; x++) {
109            *bitmap->getAddr32(x, y) = textureData[x][y];
110        }
111    }
112}
113
114// This GM attempts to make visible any issues drawBitmapRectToRect may have
115// with partial source rects. In this case the eight pixels on the border
116// should be half the width/height of the central pixel, i.e.:
117//                         __|____|__
118//                           |    |
119//                         __|____|__
120//                           |    |
121class DrawBitmapRect3 : public skiagm::GM {
122public:
123    DrawBitmapRect3() {
124        this->setBGColor(SK_ColorBLACK);
125    }
126
127protected:
128    virtual SkString onShortName() SK_OVERRIDE {
129        SkString str;
130        str.printf("3x3bitmaprect");
131        return str;
132    }
133
134    virtual SkISize onISize() SK_OVERRIDE {
135        return SkISize::Make(640, 480);
136    }
137
138    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
139
140        SkBitmap bitmap;
141        make_3x3_bitmap(&bitmap);
142
143        SkRect srcR = { 0.5f, 0.5f, 2.5f, 2.5f };
144        SkRect dstR = { 100, 100, 300, 200 };
145
146        canvas->drawBitmapRectToRect(bitmap, &srcR, dstR, NULL);
147    }
148
149private:
150    typedef skiagm::GM INHERITED;
151};
152
153//////////////////////////////////////////////////////////////////////////////
154static void make_big_bitmap(SkBitmap* bitmap) {
155
156    static const int gXSize = 4096;
157    static const int gYSize = 4096;
158    static const int gBorderWidth = 10;
159
160    bitmap->setConfig(SkBitmap::kARGB_8888_Config, gXSize, gYSize);
161    bitmap->allocPixels();
162
163    SkAutoLockPixels lock(*bitmap);
164    for (int y = 0; y < gYSize; ++y) {
165        for (int x = 0; x < gXSize; ++x) {
166            if (x <= gBorderWidth || x >= gXSize-gBorderWidth ||
167                y <= gBorderWidth || y >= gYSize-gBorderWidth) {
168                *bitmap->getAddr32(x, y) = 0x88FFFFFF;
169            } else {
170                *bitmap->getAddr32(x, y) = 0x88FF0000;
171            }
172        }
173    }
174}
175
176// This GM attempts to reveal any issues we may have when the GPU has to
177// break up a large texture in order to draw it. The XOR transfer mode will
178// create stripes in the image if there is imprecision in the destination
179// tile placement.
180class DrawBitmapRect4 : public skiagm::GM {
181    bool fUseIRect;
182public:
183    DrawBitmapRect4(bool useIRect) : fUseIRect(useIRect) {
184        this->setBGColor(0x88444444);
185    }
186
187protected:
188    virtual SkString onShortName() SK_OVERRIDE {
189        SkString str;
190        str.printf("bigbitmaprect_%s", fUseIRect ? "i" : "s");
191        return str;
192    }
193
194    virtual SkISize onISize() SK_OVERRIDE {
195        return SkISize::Make(640, 480);
196    }
197
198    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
199
200        SkXfermode* mode = SkXfermode::Create(SkXfermode::kXor_Mode);
201
202        SkPaint paint;
203        paint.setAlpha(128);
204        paint.setXfermode(mode)->unref();
205
206        SkBitmap bitmap;
207        make_big_bitmap(&bitmap);
208
209        SkRect srcR1 = { 0.0f, 0.0f, 4096.0f, 2040.0f };
210        SkRect dstR1 = { 10.1f, 10.1f, 629.9f, 400.9f };
211
212        SkRect srcR2 = { 4085.0f, 10.0f, 4087.0f, 12.0f };
213        SkRect dstR2 = { 10, 410, 30, 430 };
214
215        if (!fUseIRect) {
216            canvas->drawBitmapRectToRect(bitmap, &srcR1, dstR1, &paint);
217            canvas->drawBitmapRectToRect(bitmap, &srcR2, dstR2, &paint);
218        } else {
219            SkIRect iSrcR1, iSrcR2;
220
221            srcR1.roundOut(&iSrcR1);
222            srcR2.roundOut(&iSrcR2);
223
224            canvas->drawBitmapRect(bitmap, &iSrcR1, dstR1, &paint);
225            canvas->drawBitmapRect(bitmap, &iSrcR2, dstR2, &paint);
226        }
227    }
228
229private:
230    typedef skiagm::GM INHERITED;
231};
232
233//////////////////////////////////////////////////////////////////////////////
234
235static skiagm::GM* MyFactory0(void*) { return new DrawBitmapRect2(false); }
236static skiagm::GM* MyFactory1(void*) { return new DrawBitmapRect2(true); }
237
238static skiagm::GM* MyFactory2(void*) { return new DrawBitmapRect3(); }
239
240#ifndef SK_BUILD_FOR_ANDROID
241static skiagm::GM* MyFactory3(void*) { return new DrawBitmapRect4(false); }
242static skiagm::GM* MyFactory4(void*) { return new DrawBitmapRect4(true); }
243#endif
244
245static skiagm::GMRegistry reg0(MyFactory0);
246static skiagm::GMRegistry reg1(MyFactory1);
247
248static skiagm::GMRegistry reg2(MyFactory2);
249
250#ifndef SK_BUILD_FOR_ANDROID
251static skiagm::GMRegistry reg3(MyFactory3);
252static skiagm::GMRegistry reg4(MyFactory4);
253#endif
254