blob: 5a2fa01db785d73e17175d7616063282627c8de2 [file] [log] [blame]
scroggo@google.com7b056592013-11-05 15:57:21 +00001/*
2* Copyright 2013 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 "gm.h"
9#include "SkBlurMask.h"
10#include "SkBlurMaskFilter.h"
11#include "SkCanvas.h"
12#include "SkColorFilter.h"
13#include "SkLayerDrawLooper.h"
14#include "SkPaint.h"
15#include "SkPath.h"
16#include "SkPoint.h"
17#include "SkRect.h"
18#include "SkRRect.h"
19#include "SkString.h"
20#include "SkXfermode.h"
21
22class BlurRoundRectGM : public skiagm::GM {
23public:
24 BlurRoundRectGM(int width, int height,
25 // X and Y radii for the upper left corner
26 int ulX, int ulY,
27 // X and Y radii for the upper right corner
28 int urX, int urY,
29 // X and Y radii for the lower right corner
30 int lrX, int lrY,
31 // X and Y radii for the lower left corner
32 int llX, int llY,
33 int scaleX, int scaleY)
34 : fName("blurroundrect")
35 , fWidth(width)
36 , fHeight(height)
scroggo@google.com770269d2013-11-05 17:02:07 +000037 , fScaleX(SkIntToScalar(scaleX))
38 , fScaleY(SkIntToScalar(scaleY)) {
scroggo@google.com7b056592013-11-05 15:57:21 +000039 fName.appendf("-WH[%ix%i]-UL[%ix%i]-UR[%ix%i]-LR[%ix%i]-LL[%ix%i]-scale[%ix%i]",
40 width, height,
41 ulX, ulY,
42 urX, urY,
43 lrX, lrY,
44 llX, llY,
45 scaleX, scaleY);
46 SkVector radii[4];
47 radii[0].set(SkIntToScalar(ulX), SkIntToScalar(ulY));
48 radii[1].set(SkIntToScalar(urX), SkIntToScalar(urY));
49 radii[2].set(SkIntToScalar(lrX), SkIntToScalar(lrY));
50 radii[3].set(SkIntToScalar(llX), SkIntToScalar(llY));
scroggo@google.com770269d2013-11-05 17:02:07 +000051 SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight));
scroggo@google.com7b056592013-11-05 15:57:21 +000052 fRRect.setRectRadii(r, radii);
53 }
54
55 virtual SkString onShortName() SK_OVERRIDE {
56 return fName;
57 }
58
59 virtual SkISize onISize() SK_OVERRIDE {
60 SkISize size = this->getUnscaledSize();
61 return SkISize::Make(SkScalarCeilToInt(SkScalarMul(size.fWidth, fScaleX)),
62 SkScalarCeilToInt(SkScalarMul(size.fHeight, fScaleY)));
63 }
64
65 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
66 canvas->scale(fScaleX, fScaleY);
67 }
68
69 const SkRRect& getRRect() const {
70 return fRRect;
71 }
72
73 // The subclass will implement this to inform us how big they
74 // draw before scaling.
75 virtual SkISize getUnscaledSize() const = 0;
76
77 // So subclasses can modify the name.
78 SkString* getName() {
79 return &fName;
80 }
81
82private:
83 SkString fName;
84 const int fWidth;
85 const int fHeight;
86 const SkScalar fScaleX;
87 const SkScalar fScaleY;
88 SkRRect fRRect;
89 typedef skiagm::GM INHERITED;
90};
91
92class SKPBlurRoundRectGM : public BlurRoundRectGM {
93public:
94 SKPBlurRoundRectGM(int width, int height,
95 int ulX, int ulY,
96 int urX, int urY,
97 int lrX, int lrY,
98 int llX, int llY,
99 int scaleX, int scaleY)
100 : INHERITED(width, height, ulX, ulY, urX, urY, lrX, lrY, llX, llY, scaleX, scaleY) {
101 this->getName()->prepend("skp-");
102 }
103
104protected:
105 virtual SkISize getUnscaledSize() const SK_OVERRIDE {
scroggo@google.com28f43db2013-11-05 16:19:32 +0000106 return SkISize::Make(SkScalarCeilToInt(this->getRRect().rect().width()),
107 SkScalarCeilToInt(this->getRRect().rect().height()));
scroggo@google.com7b056592013-11-05 15:57:21 +0000108 }
109
110 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
111 this->INHERITED::onDraw(canvas);
112 SkLayerDrawLooper* looper = new SkLayerDrawLooper;
113 {
114 SkLayerDrawLooper::LayerInfo info;
115 info.fFlagsMask = 0;
116 info.fPaintBits = 40;
117 info.fColorMode = SkXfermode::kSrc_Mode;
118 info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0));
119 info.fPostTranslate = false;
120 SkPaint* paint = looper->addLayerOnTop(info);
121 SkMaskFilter* maskFilter = SkBlurMaskFilter::Create(SK_ScalarHalf,
122 SkBlurMaskFilter::kNormal_BlurStyle,
123 SkBlurMaskFilter::kHighQuality_BlurFlag);
124 paint->setMaskFilter(maskFilter)->unref();
scroggo@google.com5fdef982013-11-05 16:28:38 +0000125 SkColorFilter* colorFilter = SkColorFilter::CreateModeFilter(SK_ColorLTGRAY,
scroggo@google.com7b056592013-11-05 15:57:21 +0000126 SkXfermode::kSrcIn_Mode);
127 paint->setColorFilter(colorFilter)->unref();
scroggo@google.com5fdef982013-11-05 16:28:38 +0000128 paint->setColor(SK_ColorGRAY);
scroggo@google.com7b056592013-11-05 15:57:21 +0000129 }
130 {
131 SkLayerDrawLooper::LayerInfo info;
132 looper->addLayerOnTop(info);
133 }
134 SkPaint paint;
135 canvas->drawRect(this->getRRect().rect(), paint);
136
137 paint.setLooper(looper)->unref();
scroggo@google.com5fdef982013-11-05 16:28:38 +0000138 paint.setColor(SK_ColorCYAN);
scroggo@google.com7b056592013-11-05 15:57:21 +0000139 paint.setAntiAlias(true);
140
141 canvas->drawRRect(this->getRRect(), paint);
142 }
143
144private:
145 typedef BlurRoundRectGM INHERITED;
146};
147
148class SimpleBlurRoundRectGM : public BlurRoundRectGM {
149public:
150 SimpleBlurRoundRectGM(int width, int height,
151 int blurRadius, int cornerRadius,
152 int scaleX = 1, int scaleY = 1)
153 : INHERITED(width, height, cornerRadius, cornerRadius,
154 cornerRadius, cornerRadius, cornerRadius,
155 cornerRadius, cornerRadius, cornerRadius, scaleX, scaleY)
156 , fBlurRadius(blurRadius) {
157 // For now at least, change the name to reflect only the
158 // variables that are changing.
159 this->getName()->printf("blurround-blur[%i]-corner[%i]-scale[%ix%i]", fBlurRadius, cornerRadius, scaleX, scaleY);
160 }
161
162protected:
163 virtual SkISize getUnscaledSize() const SK_OVERRIDE {
scroggo@google.com28f43db2013-11-05 16:19:32 +0000164 return SkISize::Make(SkScalarCeilToInt(this->getRRect().rect().width() + 20),
165 SkScalarCeilToInt(this->getRRect().rect().height() + 20));
scroggo@google.com7b056592013-11-05 15:57:21 +0000166 }
167
168 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
169 // Handle the scaling.
170 this->INHERITED::onDraw(canvas);
scroggo@google.com770269d2013-11-05 17:02:07 +0000171 canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
scroggo@google.com9d3c4222013-11-05 17:29:23 +0000172 SkMaskFilter* filter = SkBlurMaskFilter::Create(SkIntToScalar(fBlurRadius),
scroggo@google.com7b056592013-11-05 15:57:21 +0000173 SkBlurMaskFilter::kNormal_BlurStyle);
174 SkPaint paint;
175 paint.setColor(SK_ColorBLUE);
176 paint.setMaskFilter(filter)->unref();
177 canvas->drawRRect(this->getRRect(), paint);
178 }
179private:
180 const int fBlurRadius;
181
182 typedef BlurRoundRectGM INHERITED;
183};
184
185// Create one with dimensions/rounded corners based on the skp
186DEF_GM(return new SKPBlurRoundRectGM(600, 5514, 6, 6, 6, 6, 6, 6, 6, 6, 1, 1);)
187// Same radii, much smaller rectangle
188DEF_GM(return new SKPBlurRoundRectGM(100, 100, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2);)
189// Rounded rect with two opposite corners with large radii, the other two
190// small.
191DEF_GM(return new SKPBlurRoundRectGM(100, 100, 30, 30, 10, 10, 30, 30, 10, 10, 3, 4);)
192DEF_GM(return new SKPBlurRoundRectGM(100, 100, 90, 90, 90, 90, 90, 90, 90, 90, 2, 3);)
193
194// Try a few blur values with a small corner radius
195DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 1, 1));
196DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 3, 1, 2, 2));
197DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 6, 1));
198DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 10, 1, 3, 3));
199
200// Now a few blur values with a larger corner radius
201DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 1, 3, 2, 2));
202DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 3, 3));
203DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 6, 3, 3, 3));
204DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 10, 3));
205
206// Even larger corner radius
207DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 1, 6, 2, 4));
208DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 3, 6));
209DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 6, 6));
210DEF_GM(return new SimpleBlurRoundRectGM(100, 100, 10, 6, 1, 3));
211