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 "SkCanvas.h"
10#include "SkPath.h"
11
12/** Draw a 2px border around the target, then red behind the target;
13    set the clip to match the target, then draw >> the target in blue.
14*/
15
16static void draw(SkCanvas* canvas, SkRect& target, int x, int y) {
17    SkPaint borderPaint;
18    borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
19    borderPaint.setAntiAlias(true);
20    SkPaint backgroundPaint;
21    backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0));
22    backgroundPaint.setAntiAlias(true);
23    SkPaint foregroundPaint;
24    foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD));
25    foregroundPaint.setAntiAlias(true);
26
27    canvas->save();
28    canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
29    target.inset(SkIntToScalar(-2), SkIntToScalar(-2));
30    canvas->drawRect(target, borderPaint);
31    target.inset(SkIntToScalar(2), SkIntToScalar(2));
32    canvas->drawRect(target, backgroundPaint);
33    canvas->clipRect(target, SkRegion::kIntersect_Op, true);
34    target.inset(SkIntToScalar(-4), SkIntToScalar(-4));
35    canvas->drawRect(target, foregroundPaint);
36    canvas->restore();
37}
38
39static void draw_square(SkCanvas* canvas, int x, int y) {
40    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1));
41    draw(canvas, target, x, y);
42}
43
44static void draw_column(SkCanvas* canvas, int x, int y) {
45    SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1));
46    draw(canvas, target, x, y);
47}
48
49static void draw_bar(SkCanvas* canvas, int x, int y) {
50    SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1));
51    draw(canvas, target, x, y);
52}
53
54static void draw_rect_tests(SkCanvas* canvas) {
55    draw_square(canvas, 10, 10);
56    draw_column(canvas, 30, 10);
57    draw_bar(canvas, 10, 30);
58}
59
60/**
61   Test a set of clipping problems discovered while writing blitAntiRect,
62   and test all the code paths through the clipping blitters.
63   Each region should show as a blue center surrounded by a 2px green
64   border, with no red.
65*/
66
67class AAClipGM : public skiagm::GM {
68public:
69    AAClipGM() {
70
71    }
72
73protected:
74    virtual SkString onShortName() SK_OVERRIDE {
75        return SkString("aaclip");
76    }
77
78    virtual SkISize onISize() SK_OVERRIDE {
79        return SkISize::Make(240, 120);
80    }
81
82    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
83        // Initial pixel-boundary-aligned draw
84        draw_rect_tests(canvas);
85
86        // Repeat 4x with .2, .4, .6, .8 px offsets
87        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
88        canvas->translate(SkIntToScalar(50), 0);
89        draw_rect_tests(canvas);
90
91        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
92        canvas->translate(SkIntToScalar(50), 0);
93        draw_rect_tests(canvas);
94
95        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
96        canvas->translate(SkIntToScalar(50), 0);
97        draw_rect_tests(canvas);
98
99        canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
100        canvas->translate(SkIntToScalar(50), 0);
101        draw_rect_tests(canvas);
102    }
103
104    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }
105
106private:
107    typedef skiagm::GM INHERITED;
108};
109
110DEF_GM( return SkNEW(AAClipGM); )
111
112/////////////////////////////////////////////////////////////////////////
113
114#ifdef SK_BUILD_FOR_MAC
115
116static SkCanvas* make_canvas(const SkBitmap& bm) {
117    const SkImageInfo& info = bm.info();
118    if (info.bytesPerPixel() == 4) {
119        return SkCanvas::NewRasterDirectN32(info.width(), info.height(),
120                                            (SkPMColor*)bm.getPixels(),
121                                            bm.rowBytes());
122    } else {
123        return SkNEW_ARGS(SkCanvas, (bm));
124    }
125}
126
127#include "SkCGUtils.h"
128static void test_image(SkCanvas* canvas, const SkImageInfo& info) {
129    SkBitmap bm;
130    bm.allocPixels(info);
131
132    SkAutoTUnref<SkCanvas> newc(make_canvas(bm));
133    if (info.isOpaque()) {
134        bm.eraseColor(SK_ColorGREEN);
135    } else {
136        bm.eraseColor(0);
137    }
138
139    SkPaint paint;
140    paint.setAntiAlias(true);
141    paint.setColor(SK_ColorBLUE);
142    newc->drawCircle(50, 50, 49, paint);
143    canvas->drawBitmap(bm, 10, 10);
144
145    CGImageRef image = SkCreateCGImageRefWithColorspace(bm, NULL);
146
147    SkBitmap bm2;
148    SkCreateBitmapFromCGImage(&bm2, image);
149    CGImageRelease(image);
150
151    canvas->drawBitmap(bm2, 10, 120);
152}
153
154class CGImageGM : public skiagm::GM {
155public:
156    CGImageGM() {}
157
158protected:
159    virtual SkString onShortName() SK_OVERRIDE {
160        return SkString("cgimage");
161    }
162
163    virtual SkISize onISize() SK_OVERRIDE {
164        return SkISize::Make(800, 250);
165    }
166
167    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
168        const struct {
169            SkColorType fCT;
170            SkAlphaType fAT;
171        } rec[] = {
172            { kRGB_565_SkColorType, kOpaque_SkAlphaType },
173
174            { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
175            { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
176            { kRGBA_8888_SkColorType, kOpaque_SkAlphaType },
177
178            { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
179            { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
180            { kBGRA_8888_SkColorType, kOpaque_SkAlphaType },
181        };
182
183        for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
184            SkImageInfo info = SkImageInfo::Make(100, 100, rec[i].fCT, rec[i].fAT);
185            test_image(canvas, info);
186            canvas->translate(info.width() + 10, 0);
187        }
188    }
189
190    virtual uint32_t onGetFlags() const SK_OVERRIDE { return kSkipPipe_Flag; }
191
192private:
193    typedef skiagm::GM INHERITED;
194};
195
196#if 0 // Disabled pending fix from reed@
197DEF_GM( return SkNEW(CGImageGM); )
198#endif
199#endif
200