SampleXfermodesBlur.cpp revision 7ce661d19c5cf4484305a1b20c44bd111f129847
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 "SampleCode.h"
9#include "SkView.h"
10#include "SkCanvas.h"
11#include "Sk64.h"
12#include "SkCornerPathEffect.h"
13#include "SkGradientShader.h"
14#include "SkGraphics.h"
15#include "SkImageDecoder.h"
16#include "SkKernel33MaskFilter.h"
17#include "SkPath.h"
18#include "SkRandom.h"
19#include "SkRegion.h"
20#include "SkShader.h"
21#include "SkUtils.h"
22#include "SkColorPriv.h"
23#include "SkColorFilter.h"
24#include "SkTime.h"
25#include "SkTypeface.h"
26#include "SkXfermode.h"
27
28#include "SkStream.h"
29#include "SkXMLParser.h"
30#include "SkColorPriv.h"
31#include "SkImageDecoder.h"
32#include "SkBlurMaskFilter.h"
33
34static void setNamedTypeface(SkPaint* paint, const char name[]) {
35    SkTypeface* face = SkTypeface::CreateFromName(name, SkTypeface::kNormal);
36    paint->setTypeface(face);
37    SkSafeUnref(face);
38}
39
40static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };
41
42class XfermodesBlurView : public SampleView {
43    SkBitmap    fBG;
44    SkBitmap    fSrcB, fDstB;
45
46    void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha,
47                   SkScalar x, SkScalar y) {
48        SkPaint p;
49        SkMaskFilter* mf = SkBlurMaskFilter::Create(5, SkBlurMaskFilter::kNormal_BlurStyle,
50                                                    SkBlurMaskFilter::kNone_BlurFlag);
51        p.setMaskFilter(mf)->unref();
52
53        SkScalar ww = SkIntToScalar(W);
54        SkScalar hh = SkIntToScalar(H);
55
56        // draw a circle covering the upper
57        // left three quarters of the canvas
58        p.setColor(0xFFCC44FF);
59        SkRect r;
60        r.set(0, 0, ww*3/4, hh*3/4);
61        r.offset(x, y);
62        canvas->drawOval(r, p);
63
64        p.setXfermode(mode);
65
66        // draw a square overlapping the circle
67        // in the lower right of the canvas
68        p.setColor(0x00AA6633 | alpha << 24);
69        r.set(ww/3, hh/3, ww*19/20, hh*19/20);
70        r.offset(x, y);
71        canvas->drawRect(r, p);
72    }
73
74public:
75    const static int W = 64;
76    const static int H = 64;
77    XfermodesBlurView() {
78        fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
79        fBG.setPixels(gBG);
80        fBG.setIsOpaque(true);
81    }
82
83protected:
84    // overrides from SkEventSink
85    virtual bool onQuery(SkEvent* evt) {
86        if (SampleCode::TitleQ(*evt)) {
87            SampleCode::TitleR(evt, "XfermodesBlur");
88            return true;
89        }
90        return this->INHERITED::onQuery(evt);
91    }
92
93    virtual void onDrawContent(SkCanvas* canvas) {
94        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
95
96        if (false) {
97            SkPaint paint;
98            paint.setAntiAlias(true);
99            paint.setTextSize(50);
100            paint.setTypeface(SkTypeface::CreateFromName("Arial Unicode MS", SkTypeface::kNormal));
101            SkSafeUnref(paint.getTypeface());
102            char buffer[10];
103            size_t len = SkUTF8_FromUnichar(0x8500, buffer);
104            canvas->drawText(buffer, len, 40, 40, paint);
105            return;
106        }
107        if (false) {
108            SkPaint paint;
109            paint.setAntiAlias(true);
110
111            SkRect r0 = { 0, 0, 10.5f, 20 };
112            SkRect r1 = { 10.5f, 10, 20, 30 };
113            paint.setColor(SK_ColorRED);
114            canvas->drawRect(r0, paint);
115            paint.setColor(SK_ColorBLUE);
116            canvas->drawRect(r1, paint);
117            return;
118        }
119
120        const struct {
121            SkXfermode::Mode  fMode;
122            const char*         fLabel;
123        } gModes[] = {
124            { SkXfermode::kClear_Mode,    "Clear"     },
125            { SkXfermode::kSrc_Mode,      "Src"       },
126            { SkXfermode::kDst_Mode,      "Dst"       },
127            { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
128            { SkXfermode::kDstOver_Mode,  "DstOver"   },
129            { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
130            { SkXfermode::kDstIn_Mode,    "DstIn"     },
131            { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
132            { SkXfermode::kDstOut_Mode,   "DstOut"    },
133            { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
134            { SkXfermode::kDstATop_Mode,  "DstATop"   },
135            { SkXfermode::kXor_Mode,      "Xor"       },
136
137            { SkXfermode::kPlus_Mode,         "Plus"          },
138            /*{ SkXfermode::kModulate_Mode,     "Modulate"      },
139            { SkXfermode::kScreen_Mode,       "Screen"        },
140            { SkXfermode::kOverlay_Mode,      "Overlay"       },
141            { SkXfermode::kDarken_Mode,       "Darken"        },
142            { SkXfermode::kLighten_Mode,      "Lighten"       },
143            { SkXfermode::kColorDodge_Mode,   "ColorDodge"    },
144            { SkXfermode::kColorBurn_Mode,    "ColorBurn"     },
145            { SkXfermode::kHardLight_Mode,    "HardLight"     },
146            { SkXfermode::kSoftLight_Mode,    "SoftLight"     },
147            { SkXfermode::kDifference_Mode,   "Difference"    },
148            { SkXfermode::kExclusion_Mode,    "Exclusion"     },*/
149        };
150
151        const SkScalar w = SkIntToScalar(W);
152        const SkScalar h = SkIntToScalar(H);
153        SkShader* s = SkShader::CreateBitmapShader(fBG,
154                                                   SkShader::kRepeat_TileMode,
155                                                   SkShader::kRepeat_TileMode);
156        SkMatrix m;
157        m.setScale(SkIntToScalar(6), SkIntToScalar(6));
158        s->setLocalMatrix(m);
159
160        SkPaint labelP;
161        labelP.setAntiAlias(true);
162        labelP.setLCDRenderText(true);
163        labelP.setTextAlign(SkPaint::kCenter_Align);
164        setNamedTypeface(&labelP, "Menlo Regular");
165
166        const int W = 5;
167
168        SkScalar x0 = 0;
169        for (int twice = 0; twice < 2; twice++) {
170            SkScalar x = x0, y = 0;
171            for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
172                SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);
173                SkAutoUnref aur(mode);
174                SkRect r;
175                r.set(x, y, x+w, y+h);
176
177                SkPaint p;
178                p.setStyle(SkPaint::kFill_Style);
179                p.setShader(s);
180                canvas->drawRect(r, p);
181
182                canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
183                draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
184                canvas->restore();
185
186                r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
187                p.setStyle(SkPaint::kStroke_Style);
188                p.setShader(NULL);
189                canvas->drawRect(r, p);
190
191                canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
192                                 x + w/2, y - labelP.getTextSize()/2, labelP);
193                x += w + SkIntToScalar(10);
194                if ((i % W) == W - 1) {
195                    x = x0;
196                    y += h + SkIntToScalar(30);
197                }
198            }
199            x0 += SkIntToScalar(400);
200        }
201        s->unref();
202    }
203
204private:
205    typedef SampleView INHERITED;
206};
207
208//////////////////////////////////////////////////////////////////////////////
209
210static SkView* MyFactory() { return new XfermodesBlurView; }
211static SkViewRegister reg(MyFactory);
212