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 "SampleCode.h"
9 #include "SkView.h"
10 #include "SkCanvas.h"
11 #include "SkDevice.h"
12 #include "SkColorPriv.h"
13 #include "SkShader.h"
14 
15 static const struct {
16     SkXfermode::Mode  fMode;
17     const char*         fLabel;
18 } gModes[] = {
19     { SkXfermode::kClear_Mode,    "Clear"     },
20     { SkXfermode::kSrc_Mode,      "Src"       },
21     { SkXfermode::kDst_Mode,      "Dst"       },
22     { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
23     { SkXfermode::kDstOver_Mode,  "DstOver"   },
24     { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
25     { SkXfermode::kDstIn_Mode,    "DstIn"     },
26     { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
27     { SkXfermode::kDstOut_Mode,   "DstOut"    },
28     { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
29     { SkXfermode::kDstATop_Mode,  "DstATop"   },
30     { SkXfermode::kXor_Mode,      "Xor"       },
31 };
32 
33 const int gWidth = 64;
34 const int gHeight = 64;
35 const SkScalar W = SkIntToScalar(gWidth);
36 const SkScalar H = SkIntToScalar(gHeight);
37 
drawCell(SkCanvas * canvas,SkXfermode * mode,SkAlpha a0,SkAlpha a1)38 static SkScalar drawCell(SkCanvas* canvas, SkXfermode* mode, SkAlpha a0, SkAlpha a1) {
39 
40     SkPaint paint;
41     paint.setAntiAlias(true);
42 
43     SkRect r = SkRect::MakeWH(W, H);
44     r.inset(W/10, H/10);
45 
46     paint.setColor(SK_ColorBLUE);
47     paint.setAlpha(a0);
48     canvas->drawOval(r, paint);
49 
50     paint.setColor(SK_ColorRED);
51     paint.setAlpha(a1);
52     paint.setXfermode(mode);
53     for (int angle = 0; angle < 24; ++angle) {
54         SkScalar x = SkScalarCos(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gWidth;
55         SkScalar y = SkScalarSin(SkIntToScalar(angle) * (SK_ScalarPI * 2) / 24) * gHeight;
56         paint.setStrokeWidth(SK_Scalar1 * angle * 2 / 24);
57         canvas->drawLine(W/2, H/2, W/2 + x, H/2 + y, paint);
58     }
59 
60     return H;
61 }
62 
make_bg_shader()63 static SkShader* make_bg_shader() {
64     SkBitmap bm;
65     bm.allocN32Pixels(2, 2);
66     *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
67     *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = SkPackARGB32(0xFF, 0xCC, 0xCC, 0xCC);
68 
69     SkMatrix m;
70     m.setScale(SkIntToScalar(6), SkIntToScalar(6));
71 
72     return SkShader::CreateBitmapShader(bm,
73                                         SkShader::kRepeat_TileMode,
74                                         SkShader::kRepeat_TileMode,
75                                         &m);
76 }
77 
78 class HairModesView : public SampleView {
79     SkPaint fBGPaint;
80 public:
HairModesView()81     HairModesView() {
82         fBGPaint.setShader(make_bg_shader())->unref();
83     }
84 
85 protected:
86     // overrides from SkEventSink
onQuery(SkEvent * evt)87     virtual bool onQuery(SkEvent* evt) {
88         if (SampleCode::TitleQ(*evt)) {
89             SampleCode::TitleR(evt, "HairlineModes");
90             return true;
91         }
92         return this->INHERITED::onQuery(evt);
93     }
94 
onDrawContent(SkCanvas * canvas)95     virtual void onDrawContent(SkCanvas* canvas) {
96         const SkRect bounds = SkRect::MakeWH(W, H);
97         static const SkAlpha gAlphaValue[] = { 0xFF, 0x88, 0x88 };
98 
99         canvas->translate(SkIntToScalar(4), SkIntToScalar(4));
100 
101         for (int alpha = 0; alpha < 4; ++alpha) {
102             canvas->save();
103             canvas->save();
104             for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); ++i) {
105                 if (6 == i) {
106                     canvas->restore();
107                     canvas->translate(W * 5, 0);
108                     canvas->save();
109                 }
110                 SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
111 
112                 canvas->drawRect(bounds, fBGPaint);
113                 canvas->saveLayer(&bounds, nullptr);
114                 SkScalar dy = drawCell(canvas, mode,
115                                        gAlphaValue[alpha & 1],
116                                        gAlphaValue[alpha & 2]);
117                 canvas->restore();
118 
119                 canvas->translate(0, dy * 5 / 4);
120                 SkSafeUnref(mode);
121             }
122             canvas->restore();
123             canvas->restore();
124             canvas->translate(W * 5 / 4, 0);
125         }
126     }
127 
128 private:
129     typedef SampleView INHERITED;
130 };
131 
132 ///////////////////////////////////////////////////////////////////////////////
133 
MyFactory()134 static SkView* MyFactory() { return new HairModesView; }
135 static SkViewRegister reg(MyFactory);
136