Home | History | Annotate | Download | only in gm
      1 
      2 /*
      3  * Copyright 2013 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 #include "gm.h"
     10 #include "SkTArray.h"
     11 #include "SkRandom.h"
     12 #include "SkMatrix.h"
     13 #include "SkBlurMaskFilter.h"
     14 #include "SkGradientShader.h"
     15 #include "SkBlurDrawLooper.h"
     16 #include "SkRect.h"
     17 #include "SkRRect.h"
     18 
     19 namespace skiagm {
     20 
     21 class RoundRectGM : public GM {
     22 public:
     23     RoundRectGM() {
     24         this->setBGColor(0xFF000000);
     25         this->makePaints();
     26         this->makeMatrices();
     27     }
     28 
     29 protected:
     30     virtual uint32_t onGetFlags() const SK_OVERRIDE {
     31         return kSkipTiled_Flag;
     32     }
     33 
     34     virtual SkString onShortName() SK_OVERRIDE {
     35         return SkString("roundrects");
     36     }
     37 
     38     virtual SkISize onISize() SK_OVERRIDE {
     39         return SkISize::Make(1200, 900);
     40     }
     41 
     42     void makePaints() {
     43         {
     44         // no AA
     45         SkPaint p;
     46         fPaints.push_back(p);
     47         }
     48 
     49         {
     50         // AA
     51         SkPaint p;
     52         p.setAntiAlias(true);
     53         fPaints.push_back(p);
     54         }
     55 
     56         {
     57         // AA with stroke style
     58         SkPaint p;
     59         p.setAntiAlias(true);
     60         p.setStyle(SkPaint::kStroke_Style);
     61         p.setStrokeWidth(SkIntToScalar(5));
     62         fPaints.push_back(p);
     63         }
     64 
     65         {
     66         // AA with stroke style, width = 0
     67         SkPaint p;
     68         p.setAntiAlias(true);
     69         p.setStyle(SkPaint::kStroke_Style);
     70         fPaints.push_back(p);
     71         }
     72 
     73         {
     74         // AA with stroke and fill style
     75         SkPaint p;
     76         p.setAntiAlias(true);
     77         p.setStyle(SkPaint::kStrokeAndFill_Style);
     78         p.setStrokeWidth(SkIntToScalar(3));
     79         fPaints.push_back(p);
     80         }
     81     }
     82 
     83     void makeMatrices() {
     84         {
     85         SkMatrix m;
     86         m.setIdentity();
     87         fMatrices.push_back(m);
     88         }
     89 
     90         {
     91         SkMatrix m;
     92         m.setScale(SkIntToScalar(3), SkIntToScalar(2));
     93         fMatrices.push_back(m);
     94         }
     95 
     96         {
     97         SkMatrix m;
     98         m.setScale(SkIntToScalar(2), SkIntToScalar(2));
     99         fMatrices.push_back(m);
    100         }
    101 
    102         {
    103         SkMatrix m;
    104         m.setScale(SkIntToScalar(1), SkIntToScalar(2));
    105         fMatrices.push_back(m);
    106         }
    107 
    108         {
    109         SkMatrix m;
    110         m.setScale(SkIntToScalar(4), SkIntToScalar(1));
    111         fMatrices.push_back(m);
    112         }
    113 
    114         {
    115         SkMatrix m;
    116         m.setRotate(SkIntToScalar(90));
    117         fMatrices.push_back(m);
    118         }
    119 
    120         {
    121         SkMatrix m;
    122         m.setSkew(SkIntToScalar(2), SkIntToScalar(3));
    123         fMatrices.push_back(m);
    124         }
    125 
    126         {
    127         SkMatrix m;
    128         m.setRotate(SkIntToScalar(60));
    129         fMatrices.push_back(m);
    130         }
    131     }
    132 
    133     SkColor genColor(SkRandom* rand) {
    134         SkScalar hsv[3];
    135         hsv[0] = rand->nextRangeF(0.0f, 360.0f);
    136         hsv[1] = rand->nextRangeF(0.75f, 1.0f);
    137         hsv[2] = rand->nextRangeF(0.75f, 1.0f);
    138 
    139         return SkHSVToColor(hsv);
    140     }
    141 
    142     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
    143         SkRandom rand(1);
    144         canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
    145         SkRect rect = SkRect::MakeLTRB(-20, -30, 20, 30);
    146         SkRRect circleRect;
    147         circleRect.setRectXY(rect, 5, 5);
    148 
    149         const SkScalar kXStart = 60.0f;
    150         const SkScalar kYStart = 80.0f;
    151         const int kXStep = 150;
    152         const int kYStep = 160;
    153         int maxX = fMatrices.count();
    154 
    155         SkPaint rectPaint;
    156         rectPaint.setAntiAlias(true);
    157         rectPaint.setStyle(SkPaint::kStroke_Style);
    158         rectPaint.setStrokeWidth(SkIntToScalar(0));
    159         rectPaint.setColor(SK_ColorLTGRAY);
    160 
    161         int testCount = 0;
    162         for (int i = 0; i < fPaints.count(); ++i) {
    163             for (int j = 0; j < fMatrices.count(); ++j) {
    164                 canvas->save();
    165                 SkMatrix mat = fMatrices[j];
    166                 // position the roundrect, and make it at off-integer coords.
    167                 mat.postTranslate(kXStart + SK_Scalar1 * kXStep * (testCount % maxX) +
    168                                   SK_Scalar1 / 4,
    169                                   kYStart + SK_Scalar1 * kYStep * (testCount / maxX) +
    170                                   3 * SK_Scalar1 / 4);
    171                 canvas->concat(mat);
    172 
    173                 SkColor color = genColor(&rand);
    174                 fPaints[i].setColor(color);
    175 
    176                 canvas->drawRect(rect, rectPaint);
    177                 canvas->drawRRect(circleRect, fPaints[i]);
    178 
    179                 canvas->restore();
    180 
    181                 ++testCount;
    182             }
    183         }
    184 
    185         // special cases
    186 
    187         // non-scaled tall and skinny roundrect
    188         for (int i = 0; i < fPaints.count(); ++i) {
    189             SkRect rect = SkRect::MakeLTRB(-20, -60, 20, 60);
    190             SkRRect ellipseRect;
    191             ellipseRect.setRectXY(rect, 5, 10);
    192 
    193             canvas->save();
    194             // position the roundrect, and make it at off-integer coords.
    195             canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.55f + SK_Scalar1 / 4,
    196                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
    197 
    198             SkColor color = genColor(&rand);
    199             fPaints[i].setColor(color);
    200 
    201             canvas->drawRect(rect, rectPaint);
    202             canvas->drawRRect(ellipseRect, fPaints[i]);
    203             canvas->restore();
    204         }
    205 
    206         // non-scaled wide and short roundrect
    207         for (int i = 0; i < fPaints.count(); ++i) {
    208             SkRect rect = SkRect::MakeLTRB(-80, -30, 80, 30);
    209             SkRRect ellipseRect;
    210             ellipseRect.setRectXY(rect, 20, 5);
    211 
    212             canvas->save();
    213             // position the roundrect, and make it at off-integer coords.
    214             canvas->translate(kXStart + SK_Scalar1 * kXStep * 4 + SK_Scalar1 / 4,
    215                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
    216                               SK_ScalarHalf * kYStep);
    217 
    218             SkColor color = genColor(&rand);
    219             fPaints[i].setColor(color);
    220 
    221             canvas->drawRect(rect, rectPaint);
    222             canvas->drawRRect(ellipseRect, fPaints[i]);
    223             canvas->restore();
    224         }
    225 
    226         // super skinny roundrect
    227         for (int i = 0; i < fPaints.count(); ++i) {
    228             SkRect rect = SkRect::MakeLTRB(0, -60, 1, 60);
    229             SkRRect circleRect;
    230             circleRect.setRectXY(rect, 5, 5);
    231 
    232             canvas->save();
    233             // position the roundrect, and make it at off-integer coords.
    234             canvas->translate(kXStart + SK_Scalar1 * kXStep * 3.25f + SK_Scalar1 / 4,
    235                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4);
    236 
    237             SkColor color = genColor(&rand);
    238             fPaints[i].setColor(color);
    239 
    240             canvas->drawRRect(circleRect, fPaints[i]);
    241             canvas->restore();
    242         }
    243 
    244         // super short roundrect
    245         for (int i = 0; i < fPaints.count(); ++i) {
    246             SkRect rect = SkRect::MakeLTRB(-80, -1, 80, 0);
    247             SkRRect circleRect;
    248             circleRect.setRectXY(rect, 5, 5);
    249 
    250             canvas->save();
    251             // position the roundrect, and make it at off-integer coords.
    252             canvas->translate(kXStart + SK_Scalar1 * kXStep * 2.5f + SK_Scalar1 / 4,
    253                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
    254                               SK_ScalarHalf * kYStep);
    255 
    256             SkColor color = genColor(&rand);
    257             fPaints[i].setColor(color);
    258 
    259             canvas->drawRRect(circleRect, fPaints[i]);
    260             canvas->restore();
    261         }
    262 
    263         // radial gradient
    264         SkPoint center = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(0));
    265         SkColor colors[] = { SK_ColorBLUE, SK_ColorRED, SK_ColorGREEN };
    266         SkScalar pos[] = { 0, SK_ScalarHalf, SK_Scalar1 };
    267         SkAutoTUnref<SkShader> shader(SkGradientShader::CreateRadial(center,
    268                                                      SkIntToScalar(20),
    269                                                      colors,
    270                                                      pos,
    271                                                      SK_ARRAY_COUNT(colors),
    272                                                      SkShader::kClamp_TileMode));
    273 
    274         for (int i = 0; i < fPaints.count(); ++i) {
    275             canvas->save();
    276             // position the path, and make it at off-integer coords.
    277             canvas->translate(kXStart + SK_Scalar1 * kXStep * 0 + SK_Scalar1 / 4,
    278                               kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
    279                               SK_ScalarHalf * kYStep);
    280 
    281             SkColor color = genColor(&rand);
    282             fPaints[i].setColor(color);
    283             fPaints[i].setShader(shader);
    284 
    285             canvas->drawRect(rect, rectPaint);
    286             canvas->drawRRect(circleRect, fPaints[i]);
    287 
    288             fPaints[i].setShader(NULL);
    289 
    290             canvas->restore();
    291         }
    292 
    293         // strokes and radii
    294         {
    295             SkScalar radii[][2] = {
    296                 {10,10},
    297                 {5,15},
    298                 {5,15},
    299                 {5,15}
    300             };
    301 
    302             SkScalar strokeWidths[] = {
    303                 20, 10, 20, 40
    304             };
    305 
    306             for (int i = 0; i < 4; ++i) {
    307                 SkRRect circleRect;
    308                 circleRect.setRectXY(rect, radii[i][0], radii[i][1]);
    309 
    310                 canvas->save();
    311                 // position the roundrect, and make it at off-integer coords.
    312                 canvas->translate(kXStart + SK_Scalar1 * kXStep * 5 + SK_Scalar1 / 4,
    313                                   kYStart + SK_Scalar1 * kYStep * i + 3 * SK_Scalar1 / 4 +
    314                                   SK_ScalarHalf * kYStep);
    315 
    316                 SkColor color = genColor(&rand);
    317 
    318                 SkPaint p;
    319                 p.setAntiAlias(true);
    320                 p.setStyle(SkPaint::kStroke_Style);
    321                 p.setStrokeWidth(strokeWidths[i]);
    322                 p.setColor(color);
    323 
    324                 canvas->drawRRect(circleRect, p);
    325                 canvas->restore();
    326             }
    327         }
    328 
    329     }
    330 
    331 private:
    332     SkTArray<SkPaint> fPaints;
    333     SkTArray<SkMatrix> fMatrices;
    334 
    335     typedef GM INHERITED;
    336 };
    337 
    338 //////////////////////////////////////////////////////////////////////////////
    339 
    340 static GM* MyFactory(void*) { return new RoundRectGM; }
    341 static GMRegistry reg(MyFactory);
    342 
    343 }
    344