blurroundrect.cpp revision 7e6e80a6eba2ce4250466d4d61e91ad8c609a593
1/* 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 22// This GM mimics a blurred RR seen in the wild. 23class BlurRoundRectGM : public skiagm::GM { 24public: 25 BlurRoundRectGM(int width, int height, int radius) 26 : fName("blurroundrect") 27 { 28 SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 29 fRRect.setRectXY(r, SkIntToScalar(radius), SkIntToScalar(radius)); 30 fName.appendf("-WH[%ix%i]-corner[%i]", width, height, radius); 31 } 32 33 BlurRoundRectGM(int width, int height) 34 : fName("blurroundrect") { 35 fName.appendf("-WH[%ix%i]-unevenCorners", 36 width, height); 37 SkVector radii[4]; 38 radii[0].set(SkIntToScalar(30), SkIntToScalar(30)); 39 radii[1].set(SkIntToScalar(10), SkIntToScalar(10)); 40 radii[2].set(SkIntToScalar(30), SkIntToScalar(30)); 41 radii[3].set(SkIntToScalar(10), SkIntToScalar(10)); 42 SkRect r = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 43 fRRect.setRectRadii(r, radii); 44 } 45 46 virtual SkString onShortName() SK_OVERRIDE { 47 return fName; 48 } 49 50 virtual SkISize onISize() SK_OVERRIDE { 51 return SkISize::Make(SkScalarCeilToInt(fRRect.rect().width()), 52 SkScalarCeilToInt(fRRect.rect().height())); 53 } 54 55 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 56 SkLayerDrawLooper* looper = new SkLayerDrawLooper; 57 { 58 SkLayerDrawLooper::LayerInfo info; 59 info.fFlagsMask = 0; 60 info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit 61 | SkLayerDrawLooper::kColorFilter_Bit; 62 info.fColorMode = SkXfermode::kSrc_Mode; 63 info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0)); 64 info.fPostTranslate = false; 65 SkPaint* paint = looper->addLayerOnTop(info); 66 SkMaskFilter* maskFilter = SkBlurMaskFilter::Create(SK_ScalarHalf, 67 SkBlurMaskFilter::kNormal_BlurStyle, 68 SkBlurMaskFilter::kHighQuality_BlurFlag); 69 paint->setMaskFilter(maskFilter)->unref(); 70 SkColorFilter* colorFilter = SkColorFilter::CreateModeFilter(SK_ColorLTGRAY, 71 SkXfermode::kSrcIn_Mode); 72 paint->setColorFilter(colorFilter)->unref(); 73 paint->setColor(SK_ColorGRAY); 74 } 75 { 76 SkLayerDrawLooper::LayerInfo info; 77 looper->addLayerOnTop(info); 78 } 79 SkPaint paint; 80 canvas->drawRect(fRRect.rect(), paint); 81 82 paint.setLooper(looper)->unref(); 83 paint.setColor(SK_ColorCYAN); 84 paint.setAntiAlias(true); 85 86 canvas->drawRRect(fRRect, paint); 87 } 88 89private: 90 SkString fName; 91 SkRRect fRRect; 92 93 typedef skiagm::GM INHERITED; 94}; 95 96// Simpler blurred RR test cases where all the radii are the same. 97class SimpleBlurRoundRectGM : public skiagm::GM { 98public: 99 SimpleBlurRoundRectGM() 100 : fName("simpleblurroundrect") { 101 } 102 103protected: 104 virtual SkString onShortName() SK_OVERRIDE { 105 return fName; 106 } 107 108 virtual SkISize onISize() SK_OVERRIDE { 109 return SkISize::Make(750, 750); 110 } 111 112 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { 113 canvas->scale(SkFloatToScalar(1.5f), SkFloatToScalar(1.5f)); 114 115 const int blurRadii[] = { 1, 3, 6, 10 }; 116 const int cornerRadii[] = { 1, 3, 6, 10 }; 117 const SkRect r = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100)); 118 for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) { 119 SkAutoCanvasRestore autoRestore(canvas, true); 120 canvas->translate(0, (r.height() + SkIntToScalar(20)) * i); 121 for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) { 122 SkMaskFilter* filter = SkBlurMaskFilter::Create(SkIntToScalar(blurRadii[i]), 123 SkBlurMaskFilter::kNormal_BlurStyle); 124 SkPaint paint; 125 paint.setColor(SK_ColorBLUE); 126 paint.setMaskFilter(filter)->unref(); 127 128 SkRRect rrect; 129 rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]), SkIntToScalar(cornerRadii[j])); 130 canvas->drawRRect(rrect, paint); 131 canvas->translate(r.width() + SkIntToScalar(10), 0); 132 } 133 } 134 } 135private: 136 const SkString fName; 137 138 typedef skiagm::GM INHERITED; 139}; 140 141// Create one with dimensions/rounded corners based on the skp 142// 143// TODO(scroggo): Disabled in an attempt to rememdy 144// https://code.google.com/p/skia/issues/detail?id=1801 ('Win7 Test bots all failing GenerateGMs: 145// ran wrong number of tests') 146//DEF_GM(return new BlurRoundRectGM(600, 5514, 6);) 147 148// Rounded rect with two opposite corners with large radii, the other two 149// small. 150DEF_GM(return new BlurRoundRectGM(100, 100);) 151 152DEF_GM(return new SimpleBlurRoundRectGM();) 153