Home | History | Annotate | Download | only in gm
      1 
      2 /*
      3  * Copyright 2011 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 #include "gm.h"
      9 #include "SkRandom.h"
     10 #include "SkTArray.h"
     11 
     12 namespace skiagm {
     13 
     14 class ConvexPathsGM : public GM {
     15 public:
     16     ConvexPathsGM() {
     17         this->setBGColor(0xFF000000);
     18         this->makePaths();
     19     }
     20 
     21 protected:
     22     virtual SkString onShortName() {
     23         return SkString("convexpaths");
     24     }
     25 
     26 
     27     virtual SkISize onISize() {
     28         return make_isize(1200, 900);
     29     }
     30 
     31     void makePaths() {
     32         // CW
     33         fPaths.push_back().moveTo(0, 0);
     34         fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
     35                              0, 100 * SK_Scalar1);
     36         fPaths.back().lineTo(0, 0);
     37 
     38         // CCW
     39         fPaths.push_back().moveTo(0, 0);
     40         fPaths.back().lineTo(0, 100 * SK_Scalar1);
     41         fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
     42                              0, 0);
     43 
     44         // CW
     45         fPaths.push_back().moveTo(0, 50 * SK_Scalar1);
     46         fPaths.back().quadTo(50 * SK_Scalar1, 0,
     47                              100 * SK_Scalar1, 50 * SK_Scalar1);
     48         fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
     49                              0, 50 * SK_Scalar1);
     50 
     51         // CCW
     52         fPaths.push_back().moveTo(0, 50 * SK_Scalar1);
     53         fPaths.back().quadTo(50 * SK_Scalar1, 100 * SK_Scalar1,
     54                              100 * SK_Scalar1, 50 * SK_Scalar1);
     55         fPaths.back().quadTo(50 * SK_Scalar1, 0,
     56                              0, 50 * SK_Scalar1);
     57 
     58         fPaths.push_back().addRect(0, 0,
     59                                    100 * SK_Scalar1, 100 * SK_Scalar1,
     60                                    SkPath::kCW_Direction);
     61 
     62         fPaths.push_back().addRect(0, 0,
     63                                    100 * SK_Scalar1, 100 * SK_Scalar1,
     64                                    SkPath::kCCW_Direction);
     65 
     66         fPaths.push_back().addCircle(50  * SK_Scalar1, 50  * SK_Scalar1,
     67                                      50  * SK_Scalar1, SkPath::kCW_Direction);
     68 
     69         fPaths.push_back().addCircle(50  * SK_Scalar1, 50  * SK_Scalar1,
     70                                      40  * SK_Scalar1, SkPath::kCCW_Direction);
     71 
     72         fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
     73                                                     50 * SK_Scalar1,
     74                                                     100 * SK_Scalar1),
     75                                    SkPath::kCW_Direction);
     76 
     77         fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
     78                                                     100 * SK_Scalar1,
     79                                                     50 * SK_Scalar1),
     80                                    SkPath::kCCW_Direction);
     81 
     82         fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
     83                                                     100 * SK_Scalar1,
     84                                                     5 * SK_Scalar1),
     85                                    SkPath::kCCW_Direction);
     86 
     87         fPaths.push_back().addOval(SkRect::MakeXYWH(0, 0,
     88                                                     SK_Scalar1,
     89                                                     100 * SK_Scalar1),
     90                                    SkPath::kCCW_Direction);
     91 
     92         fPaths.push_back().addRoundRect(SkRect::MakeXYWH(0, 0,
     93                                                          SK_Scalar1 * 100,
     94                                                          SK_Scalar1 * 100),
     95                                         40 * SK_Scalar1, 20 * SK_Scalar1,
     96                                         SkPath::kCW_Direction);
     97 
     98         fPaths.push_back().addRoundRect(SkRect::MakeXYWH(0, 0,
     99                                                          SK_Scalar1 * 100,
    100                                                          SK_Scalar1 * 100),
    101                                         20 * SK_Scalar1, 40 * SK_Scalar1,
    102                                         SkPath::kCCW_Direction);
    103 
    104         // shallow diagonals
    105         fPaths.push_back().lineTo(100 * SK_Scalar1, SK_Scalar1);
    106         fPaths.back().lineTo(98 * SK_Scalar1, 100 * SK_Scalar1);
    107         fPaths.back().lineTo(3 * SK_Scalar1, 96 * SK_Scalar1);
    108 
    109         /*
    110         It turns out arcTos are not automatically marked as convex and they
    111         may in fact be ever so slightly concave.
    112         fPaths.push_back().arcTo(SkRect::MakeXYWH(0, 0,
    113                                                   50 * SK_Scalar1,
    114                                                   100 * SK_Scalar1),
    115                                  25 * SK_Scalar1,  130 * SK_Scalar1, false);
    116         */
    117 
    118         // cubics
    119         fPaths.push_back().cubicTo( 1 * SK_Scalar1,  1 * SK_Scalar1,
    120                                    10 * SK_Scalar1,  90 * SK_Scalar1,
    121                                     0 * SK_Scalar1, 100 * SK_Scalar1);
    122         fPaths.push_back().cubicTo(100 * SK_Scalar1,  50 * SK_Scalar1,
    123                                     20 * SK_Scalar1, 100 * SK_Scalar1,
    124                                      0 * SK_Scalar1,   0 * SK_Scalar1);
    125 
    126         // triangle where one edge is a degenerate quad
    127         fPaths.push_back().moveTo(SkFloatToScalar(8.59375f), 45 * SK_Scalar1);
    128         fPaths.back().quadTo(SkFloatToScalar(16.9921875f),   45 * SK_Scalar1,
    129                              SkFloatToScalar(31.25f),        45 * SK_Scalar1);
    130         fPaths.back().lineTo(100 * SK_Scalar1,              100 * SK_Scalar1);
    131         fPaths.back().lineTo(SkFloatToScalar(8.59375f),      45 * SK_Scalar1);
    132 
    133         // point degenerate
    134         fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
    135         fPaths.back().lineTo(50 * SK_Scalar1, 50 * SK_Scalar1);
    136 
    137         fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
    138         fPaths.back().quadTo(50 * SK_Scalar1, 50 * SK_Scalar1,
    139                              50 * SK_Scalar1, 50 * SK_Scalar1);
    140         fPaths.push_back().moveTo(50 * SK_Scalar1, 50 * SK_Scalar1);
    141         fPaths.back().cubicTo(50 * SK_Scalar1, 50 * SK_Scalar1,
    142                               50 * SK_Scalar1, 50 * SK_Scalar1,
    143                               50 * SK_Scalar1, 50 * SK_Scalar1);
    144 
    145         // moveTo only paths
    146         fPaths.push_back().moveTo(0, 0);
    147         fPaths.back().moveTo(0, 0);
    148         fPaths.back().moveTo(SK_Scalar1, SK_Scalar1);
    149         fPaths.back().moveTo(SK_Scalar1, SK_Scalar1);
    150         fPaths.back().moveTo(10 * SK_Scalar1, 10 * SK_Scalar1);
    151 
    152         fPaths.push_back().moveTo(0, 0);
    153         fPaths.back().moveTo(0, 0);
    154 
    155         // line degenerate
    156         fPaths.push_back().lineTo(100 * SK_Scalar1, 100 * SK_Scalar1);
    157         fPaths.push_back().quadTo(100 * SK_Scalar1, 100 * SK_Scalar1, 0, 0);
    158         fPaths.push_back().quadTo(100 * SK_Scalar1, 100 * SK_Scalar1,
    159                                   50 * SK_Scalar1, 50 * SK_Scalar1);
    160         fPaths.push_back().quadTo(50 * SK_Scalar1, 50 * SK_Scalar1,
    161                                   100 * SK_Scalar1, 100 * SK_Scalar1);
    162         fPaths.push_back().cubicTo(0, 0,
    163                                    0, 0,
    164                                    100 * SK_Scalar1, 100 * SK_Scalar1);
    165 
    166         // small circle. This is listed last so that it has device coords far
    167         // from the origin (small area relative to x,y values).
    168         fPaths.push_back().addCircle(0, 0, SkFloatToScalar(0.8f));
    169     }
    170 
    171     virtual void onDraw(SkCanvas* canvas) {
    172 
    173     SkPaint paint;
    174     paint.setAntiAlias(true);
    175     SkRandom rand;
    176     canvas->translate(20 * SK_Scalar1, 20 * SK_Scalar1);
    177     for (int i = 0; i < fPaths.count(); ++i) {
    178         canvas->save();
    179         // position the path, and make it at off-integer coords.
    180         canvas->translate(SK_Scalar1 * 200 * (i % 5) + SK_Scalar1 / 4,
    181                           SK_Scalar1 * 200 * (i / 5) + 3 * SK_Scalar1 / 4);
    182         SkColor color = rand.nextU();
    183         color |= 0xff000000;
    184         paint.setColor(color);
    185         SkASSERT(fPaths[i].isConvex());
    186         canvas->drawPath(fPaths[i], paint);
    187         canvas->restore();
    188     }
    189     }
    190 
    191 private:
    192     typedef GM INHERITED;
    193     SkTArray<SkPath> fPaths;
    194 };
    195 
    196 //////////////////////////////////////////////////////////////////////////////
    197 
    198 static GM* MyFactory(void*) { return new ConvexPathsGM; }
    199 static GMRegistry reg(MyFactory);
    200 
    201 }
    202 
    203