blurrect.cpp revision 57850b9daddd941f880d94faaf83f2169355a0c8
10bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens/*
266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman * Copyright 2012 Google Inc.
30bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens *
40bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens * Use of this source code is governed by a BSD-style license that can be
50bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens * found in the LICENSE file.
666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman */
70bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "gm.h"
90bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "SkBlurMaskFilter.h"
100bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "SkCanvas.h"
110bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#include "SkPath.h"
120bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens
130bac285a78df6a6d7a6b68784748b92805420ffbNicolas Capens#define STROKE_WIDTH    SkIntToScalar(10)
1466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
1566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantypedef void (*Proc)(SkCanvas*, const SkRect&, const SkPaint&);
1666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
1766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void fill_rect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
1866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    canvas->drawRect(r, p);
1966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
20c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens
2166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void stroke_rect(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
2266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    SkPaint paint(p);
2366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    paint.setStyle(SkPaint::kStroke_Style);
2466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    paint.setStrokeWidth(STROKE_WIDTH);
2566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    canvas->drawRect(r, paint);
2666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
2766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
2866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanstatic void draw_donut(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
2966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    SkRect  rect;
3066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    SkPath  path;
3166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
3266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    rect = r;
3366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    rect.outset(STROKE_WIDTH/2, STROKE_WIDTH/2);
3466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    path.addRect(rect);
3566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    rect = r;
3666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    rect.inset(STROKE_WIDTH/2, STROKE_WIDTH/2);
3766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
387551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    path.addRect(rect);
397551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    path.setFillType(SkPath::kEvenOdd_FillType);
407551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
417551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    canvas->drawPath(path, p);
427551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens}
437551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
447551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capensstatic void draw_donut_skewed(SkCanvas* canvas, const SkRect& r, const SkPaint& p) {
457551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    SkRect  rect;
467551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    SkPath  path;
477551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
487551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    rect = r;
497551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    rect.outset(STROKE_WIDTH/2, STROKE_WIDTH/2);
507551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    path.addRect(rect);
517551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    rect = r;
527551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    rect.inset(STROKE_WIDTH/2, STROKE_WIDTH/2);
537551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
547551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    rect.offset(7, -7);
557551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
567551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    path.addRect(rect);
577551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    path.setFillType(SkPath::kEvenOdd_FillType);
587551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens
597551ac6868ec1dc3965a00ff0a2003adbb2018d5Nicolas Capens    canvas->drawPath(path, p);
6066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman}
6166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
6266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman#include "SkGradientShader.h"
6366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
6466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumantypedef void (*PaintProc)(SkPaint*, SkScalar width);
65b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
66b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capensstatic void setgrad(SkPaint* paint, SkScalar width) {
67b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    SkPoint pts[] = { { 0, 0 }, { width, 0 } };
6866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    SkColor colors[] = { SK_ColorRED, SK_ColorGREEN };
69c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens    SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL, 2,
70b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens                                                 SkShader::kClamp_TileMode);
712c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu    paint->setShader(s)->unref();
722c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu}
732c2a7b29cd53cb7b06ef1b1e2177a8c90e6e0128Alexis Hetu
74b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capensstatic const char* gBlurStyle2Name[] = {
7566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    "normal",
76b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    "solid",
77b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    "outer",
78b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    "inner"
79b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens};
80b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
81b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capensclass BlurRectGM : public skiagm::GM {
82b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    SkAutoTUnref<SkMaskFilter> fMaskFilter;
83b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    SkString  fName;
84b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    PaintProc fPProc;
85b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    SkAlpha   fAlpha;
8666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanpublic:
87b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    BlurRectGM(const char name[], PaintProc pproc, U8CPU alpha,
88b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens               SkBlurMaskFilter::BlurStyle bs) :
89b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        fMaskFilter(SkBlurMaskFilter::Create(STROKE_WIDTH/2, bs,
90b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens                                       SkBlurMaskFilter::kHighQuality_BlurFlag))
91b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        , fName(name)
92b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        , fPProc(pproc)
93b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        , fAlpha(SkToU8(alpha))
94b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    {
95b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        fName.appendf("_%s", gBlurStyle2Name[bs]);
96b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    }
97b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
98b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capensprotected:
99b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    virtual SkString onShortName() {
100b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        return fName;
10166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
102b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
103b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    virtual SkISize onISize() {
104b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        return SkISize::Make(640, 480);
105b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    }
106b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
107b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens    virtual void onDraw(SkCanvas* canvas) {
108b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        canvas->translate(STROKE_WIDTH*3/2, STROKE_WIDTH*3/2);
109b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
110b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        SkRect  r = { 0, 0, 250, 120 };
111b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens
112b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        SkPaint paint;
113b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        paint.setMaskFilter(fMaskFilter);
114b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens        if (fPProc) {
115b4fb367887d4f257b20be509b8abd3ccb3a23a5aNicolas Capens            fPProc(&paint, r.width());
11666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        }
117c2534f4bc37baf48d9910d3691352ff83e3bea49Nicolas Capens        paint.setAlpha(fAlpha);
11866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
1190b65c5e3903233839197fd689895ba57b7f61a5bAlexis Hetu        static const Proc procs[] = {
12066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman            fill_rect, draw_donut, draw_donut_skewed
12166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        };
12266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
12366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        this->drawProcs(canvas, r, paint, false, procs, SK_ARRAY_COUNT(procs));
12466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        canvas->translate(r.width() * 4/3, 0);
12566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        this->drawProcs(canvas, r, paint, true, procs, SK_ARRAY_COUNT(procs));
12666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    }
12766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
12866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    virtual uint32_t onGetFlags() const { return kSkipPipe_Flag; }
12966b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman
13066b8ab22586debccb1f787d4d52b7f042d4ddeb8John Baumanprivate:
13166b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman    void drawProcs(SkCanvas* canvas, const SkRect& r, const SkPaint& paint,
13266b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                   bool doClip, const Proc procs[], size_t procsCount) {
13366b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        SkAutoCanvasRestore acr(canvas, true);
13466b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman        for (size_t i = 0; i < procsCount; ++i) {
13566b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman            if (doClip) {
13666b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                SkRect clipRect(r);
13766b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                clipRect.inset(STROKE_WIDTH/2, STROKE_WIDTH/2);
13866b8ab22586debccb1f787d4d52b7f042d4ddeb8John Bauman                canvas->save();
139                canvas->clipRect(r);
140            }
141            procs[i](canvas, r, paint);
142            if (doClip) {
143                canvas->restore();
144            }
145            canvas->translate(0, r.height() * 4/3);
146        }
147    }
148
149    typedef GM INHERITED;
150};
151
152//////////////////////////////////////////////////////////////////////////////
153
154DEF_GM(return new BlurRectGM("blurrect", NULL, 0xFF, SkBlurMaskFilter::kNormal_BlurStyle);)
155DEF_GM(return new BlurRectGM("blurrect", NULL, 0xFF, SkBlurMaskFilter::kSolid_BlurStyle);)
156DEF_GM(return new BlurRectGM("blurrect", NULL, 0xFF, SkBlurMaskFilter::kOuter_BlurStyle);)
157DEF_GM(return new BlurRectGM("blurrect", NULL, 0xFF, SkBlurMaskFilter::kInner_BlurStyle);)
158
159DEF_GM(return new BlurRectGM("blurrect_grad_80", setgrad, 0x80, SkBlurMaskFilter::kNormal_BlurStyle);)
160
161