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