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