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