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