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