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