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