Home | History | Annotate | Download | only in gm
      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 "sk_tool_utils.h"
     10 #include "SkBlurMask.h"
     11 #include "SkBlurMaskFilter.h"
     12 #include "SkCanvas.h"
     13 #include "SkColorFilter.h"
     14 #include "SkLayerDrawLooper.h"
     15 #include "SkPaint.h"
     16 #include "SkPath.h"
     17 #include "SkPoint.h"
     18 #include "SkRect.h"
     19 #include "SkRRect.h"
     20 #include "SkString.h"
     21 
     22 // This GM mimics a blurred RR seen in the wild.
     23 class BlurRoundRectGM : public skiagm::GM {
     24 public:
     25     BlurRoundRectGM(int width, int height)
     26         : fName("blurroundrect"), fWidth(width), fHeight(height) {
     27         fName.appendf("-WH-%ix%i-unevenCorners", width,  height);
     28     }
     29 
     30     SkString onShortName() override {
     31         return fName;
     32     }
     33 
     34     SkISize onISize() override {
     35         return SkISize::Make(fWidth, fHeight);
     36     }
     37 
     38     void onOnceBeforeDraw() override {
     39         SkVector radii[4];
     40         radii[0].set(SkIntToScalar(30), SkIntToScalar(30));
     41         radii[1].set(SkIntToScalar(10), SkIntToScalar(10));
     42         radii[2].set(SkIntToScalar(30), SkIntToScalar(30));
     43         radii[3].set(SkIntToScalar(10), SkIntToScalar(10));
     44         SkRect r = SkRect::MakeWH(SkIntToScalar(fWidth), SkIntToScalar(fHeight));
     45         fRRect.setRectRadii(r, radii);
     46     }
     47 
     48     void onDraw(SkCanvas* canvas) override {
     49         SkLayerDrawLooper::Builder looperBuilder;
     50         {
     51             SkLayerDrawLooper::LayerInfo info;
     52             info.fPaintBits = SkLayerDrawLooper::kMaskFilter_Bit
     53                               | SkLayerDrawLooper::kColorFilter_Bit;
     54             info.fColorMode = SkBlendMode::kSrc;
     55             info.fOffset = SkPoint::Make(SkIntToScalar(-1), SkIntToScalar(0));
     56             info.fPostTranslate = false;
     57             SkPaint* paint = looperBuilder.addLayerOnTop(info);
     58             paint->setMaskFilter(SkBlurMaskFilter::Make(
     59                     kNormal_SkBlurStyle,
     60                     SkBlurMask::ConvertRadiusToSigma(SK_ScalarHalf),
     61                     SkBlurMaskFilter::kHighQuality_BlurFlag));
     62             paint->setColorFilter(SkColorFilter::MakeModeFilter(
     63                     sk_tool_utils::color_to_565(SK_ColorLTGRAY),
     64                     SkBlendMode::kSrcIn));
     65             paint->setColor(sk_tool_utils::color_to_565(SK_ColorGRAY));
     66         }
     67         {
     68             SkLayerDrawLooper::LayerInfo info;
     69             looperBuilder.addLayerOnTop(info);
     70         }
     71         SkPaint paint;
     72         canvas->drawRect(fRRect.rect(), paint);
     73 
     74         paint.setLooper(looperBuilder.detach());
     75         paint.setColor(SK_ColorCYAN);
     76         paint.setAntiAlias(true);
     77 
     78         canvas->drawRRect(fRRect, paint);
     79     }
     80 
     81 private:
     82     SkString        fName;
     83     SkRRect         fRRect;
     84     int             fWidth, fHeight;
     85 
     86     typedef skiagm::GM INHERITED;
     87 };
     88 
     89 #include "SkGradientShader.h"
     90 /*
     91  * Spits out a dummy gradient to test blur with shader on paint
     92  */
     93 static sk_sp<SkShader> MakeRadial() {
     94     SkPoint pts[2] = {
     95         { 0, 0 },
     96         { SkIntToScalar(100), SkIntToScalar(100) }
     97     };
     98     SkShader::TileMode tm = SkShader::kClamp_TileMode;
     99     const SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, };
    100     const SkScalar pos[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
    101     SkMatrix scale;
    102     scale.setScale(0.5f, 0.5f);
    103     scale.postTranslate(5.f, 5.f);
    104     SkPoint center0, center1;
    105     center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
    106                 SkScalarAve(pts[0].fY, pts[1].fY));
    107     center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
    108                 SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
    109     return SkGradientShader::MakeTwoPointConical(center1, (pts[1].fX - pts[0].fX) / 7,
    110                                                  center0, (pts[1].fX - pts[0].fX) / 2,
    111                                                  colors, pos, SK_ARRAY_COUNT(colors), tm,
    112                                                  0, &scale);
    113 }
    114 
    115 // Simpler blurred RR test cases where all the radii are the same.
    116 class SimpleBlurRoundRectGM : public skiagm::GM {
    117 public:
    118     SimpleBlurRoundRectGM()
    119         : fName("simpleblurroundrect") {
    120     }
    121 
    122 protected:
    123 
    124     SkString onShortName() override {
    125         return fName;
    126     }
    127 
    128     SkISize onISize() override {
    129         return SkISize::Make(1000, 500);
    130     }
    131 
    132     void onDraw(SkCanvas* canvas) override {
    133         canvas->scale(1.5f, 1.5f);
    134         canvas->translate(50,50);
    135 
    136         const float blurRadii[] = { 1,5,10,20 };
    137         const int cornerRadii[] = { 1,5,10,20 };
    138         const SkRect r = SkRect::MakeWH(SkIntToScalar(25), SkIntToScalar(25));
    139         for (size_t i = 0; i < SK_ARRAY_COUNT(blurRadii); ++i) {
    140             SkAutoCanvasRestore autoRestore(canvas, true);
    141             canvas->translate(0, (r.height() + SkIntToScalar(50)) * i);
    142             for (size_t j = 0; j < SK_ARRAY_COUNT(cornerRadii); ++j) {
    143                 for (int k = 0; k <= 1; k++) {
    144                     SkPaint paint;
    145                     paint.setColor(SK_ColorBLACK);
    146                     paint.setMaskFilter(SkBlurMaskFilter::Make(kNormal_SkBlurStyle,
    147                                    SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(blurRadii[i])),
    148                                    SkBlurMaskFilter::kHighQuality_BlurFlag));
    149 
    150                     bool useRadial = SkToBool(k);
    151                     if (useRadial) {
    152                         paint.setShader(MakeRadial());
    153                     }
    154 
    155                     SkRRect rrect;
    156                     rrect.setRectXY(r, SkIntToScalar(cornerRadii[j]),
    157                                     SkIntToScalar(cornerRadii[j]));
    158                     canvas->drawRRect(rrect, paint);
    159                     canvas->translate(r.width() + SkIntToScalar(50), 0);
    160                 }
    161             }
    162         }
    163     }
    164 private:
    165     const SkString  fName;
    166 
    167     typedef         skiagm::GM INHERITED;
    168 };
    169 
    170 // Create one with dimensions/rounded corners based on the skp
    171 //
    172 // TODO(scroggo): Disabled in an attempt to rememdy
    173 // https://code.google.com/p/skia/issues/detail?id=1801 ('Win7 Test bots all failing GenerateGMs:
    174 // ran wrong number of tests')
    175 //DEF_GM(return new BlurRoundRectGM(600, 5514, 6);)
    176 
    177 // Rounded rect with two opposite corners with large radii, the other two
    178 // small.
    179 DEF_GM(return new BlurRoundRectGM(100, 100);)
    180 
    181 DEF_GM(return new SimpleBlurRoundRectGM();)
    182