1ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com/*
2ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com * Copyright 2011 Google Inc.
3ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com *
4ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com * Use of this source code is governed by a BSD-style license that can be
5ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com * found in the LICENSE file.
6ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com */
7ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
8ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "gm.h"
9ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "SkCanvas.h"
10ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "SkColorPriv.h"
11ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com#include "SkShader.h"
12ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
13ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comstatic const struct {
14ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkXfermode::Mode  fMode;
15ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    const char*         fLabel;
16ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com} gModes[] = {
17ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kClear_Mode,    "Clear"     },
18ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kSrc_Mode,      "Src"       },
19ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kDst_Mode,      "Dst"       },
20ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
21ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kDstOver_Mode,  "DstOver"   },
22ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
23ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kDstIn_Mode,    "DstIn"     },
24ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
25ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kDstOut_Mode,   "DstOut"    },
26ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
27ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kDstATop_Mode,  "DstATop"   },
28ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    { SkXfermode::kXor_Mode,      "Xor"       },
29ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com};
30ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
31ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst int gWidth = 64;
32ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst int gHeight = 64;
33ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst SkScalar W = SkIntToScalar(gWidth);
34ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comconst SkScalar H = SkIntToScalar(gHeight);
35ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
36ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comstatic SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) {
37ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
38ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkPaint paint;
39ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setAntiAlias(true);
40ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
41ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkRect r = SkRect::MakeWH(W, H);
42ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    r.inset(W/10, H/10);
43ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
44ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setColor(SK_ColorBLUE);
45ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setAlpha(a0);
46ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    canvas->drawOval(r, paint);
47ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
48ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setColor(SK_ColorRED);
49ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setAlpha(a1);
50ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    paint.setXfermode(mode);
51ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    for (int angle = 0; angle < 24; ++angle) {
52ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth;
53ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight;
54ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24);
55ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint);
56ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    }
57ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
58ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    return H;
59ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com}
60ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
61ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comstatic SkShader* make_bg_shader() {
62ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkBitmap bm;
63eb9a46cbbb475e862a084aa2224ec18d4ac5e95breed@google.com    bm.allocN32Pixels(2, 2);
64ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
65ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC);
66ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
67ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    SkMatrix m;
68ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    m.setScale(SkIntToScalar(6), SkIntToScalar(6));
699c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org    return SkShader::CreateBitmapShader(bm,
709c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                        SkShader::kRepeat_TileMode,
719c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                        SkShader::kRepeat_TileMode,
729c9005a347e9996f357bd79591bd34f74f8bbc66commit-bot@chromium.org                                        &m);
73ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com}
74ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com
75ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.comnamespace skiagm {
76ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
77ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    class HairModesGM : public GM {
78ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        SkPaint fBGPaint;
79ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
80ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    protected:
817775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com        virtual SkString onShortName() SK_OVERRIDE {
82ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            return SkString("hairmodes");
83ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        }
84ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
85f539318f0d3dba743ec1886d5d9df0fb1be628a1tfarina        virtual SkISize onISize() { return SkISize::Make(640, 480); }
86ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
877775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com        virtual void onOnceBeforeDraw() SK_OVERRIDE {
887775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com            fBGPaint.setShader(make_bg_shader())->unref();
897775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com        }
907775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com
917775d66aa0e5958c9ea55ddb8317af4d9b019220reed@google.com        virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
92ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            const SkRect bounds = SkRect::MakeWH(W, H);
93ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
94ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
95ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
96ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
97ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            for (int alpha = 0; alpha < 4; ++alpha) {
98ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->save();
99ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->save();
100ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
101ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    if (6 == i) {
102ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                        canvas->restore();
103ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                        canvas->translate(W * 5, 0);
104ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                        canvas->save();
105ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    }
106ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
107ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
108ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    canvas->drawRect(bounds, fBGPaint);
109ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    canvas->saveLayer(&bounds, NULL);
110ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    SkScalar dy = drawCell(canvas, mode,
111ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                                           gAlphaValue[alpha & 1],
112ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                                           gAlphaValue[alpha & 2]);
113ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    canvas->restore();
114ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
115ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    canvas->translate(0, dy * 5 / 4);
116ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                    SkSafeUnref(mode);
117ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                }
118ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->restore();
119ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->restore();
120ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com                canvas->translate(W * 5 / 4, 0);
121ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com            }
122ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        }
123fbc21172885fe1f028594bc9b181246c71eb106creed@google.com
124fbc21172885fe1f028594bc9b181246c71eb106creed@google.com        // disable pdf for now, since it crashes on mac
125a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org        virtual uint32_t onGetFlags() const { return kSkipPDF_Flag | kSkipTiled_Flag; }
126fbc21172885fe1f028594bc9b181246c71eb106creed@google.com
127ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    private:
128ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com        typedef GM INHERITED;
129ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    };
130ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
131ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    //////////////////////////////////////////////////////////////////////////////
132ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
133ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    static GM* MyFactory(void*) { return new HairModesGM; }
134ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com    static GMRegistry reg(MyFactory);
135ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
136ab9739777cc84bf6c7e86372ade87a4ec468d1e6reed@google.com}
137