Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2011 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 #include "gm.h"
      8 #include "SkCanvas.h"
      9 #include "SkPaint.h"
     10 #include "SkRandom.h"
     11 
     12 namespace skiagm {
     13 
     14 class QuadPathGM : public GM {
     15 public:
     16     QuadPathGM() {}
     17 
     18 protected:
     19     SkString onShortName() {
     20         return SkString("quadpath");
     21     }
     22 
     23     SkISize onISize() { return make_isize(1240, 390); }
     24 
     25     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
     26                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
     27                   SkPaint::Style style, SkPath::FillType fill,
     28                   SkScalar strokeWidth) {
     29         path.setFillType(fill);
     30         SkPaint paint;
     31         paint.setStrokeCap(cap);
     32         paint.setStrokeWidth(strokeWidth);
     33         paint.setStrokeJoin(join);
     34         paint.setColor(color);
     35         paint.setStyle(style);
     36         canvas->save();
     37         canvas->clipRect(clip);
     38         canvas->drawPath(path, paint);
     39         canvas->restore();
     40     }
     41 
     42     virtual void onDraw(SkCanvas* canvas) {
     43         struct FillAndName {
     44             SkPath::FillType fFill;
     45             const char*      fName;
     46         };
     47         static const FillAndName gFills[] = {
     48             {SkPath::kWinding_FillType, "Winding"},
     49             {SkPath::kEvenOdd_FillType, "Even / Odd"},
     50             {SkPath::kInverseWinding_FillType, "Inverse Winding"},
     51             {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
     52         };
     53         struct StyleAndName {
     54             SkPaint::Style fStyle;
     55             const char*    fName;
     56         };
     57         static const StyleAndName gStyles[] = {
     58             {SkPaint::kFill_Style, "Fill"},
     59             {SkPaint::kStroke_Style, "Stroke"},
     60             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
     61         };
     62         struct CapAndName {
     63             SkPaint::Cap  fCap;
     64             SkPaint::Join fJoin;
     65             const char*   fName;
     66         };
     67         static const CapAndName gCaps[] = {
     68             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
     69             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
     70             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
     71         };
     72         struct PathAndName {
     73             SkPath      fPath;
     74             const char* fName;
     75         };
     76         PathAndName path;
     77         path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
     78         path.fPath.quadTo(50*SK_Scalar1, 20*SK_Scalar1,
     79                           75*SK_Scalar1, 10*SK_Scalar1);
     80         path.fName = "moveTo-quad";
     81 
     82         SkPaint titlePaint;
     83         titlePaint.setColor(SK_ColorBLACK);
     84         titlePaint.setAntiAlias(true);
     85         titlePaint.setLCDRenderText(true);
     86         titlePaint.setTextSize(15 * SK_Scalar1);
     87         const char title[] = "Quad Drawn Into Rectangle Clips With "
     88                              "Indicated Style, Fill and Linecaps, with stroke width 10";
     89         canvas->drawText(title, strlen(title),
     90                             20 * SK_Scalar1,
     91                             20 * SK_Scalar1,
     92                             titlePaint);
     93 
     94         SkLCGRandom rand;
     95         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
     96         canvas->save();
     97         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
     98         canvas->save();
     99         for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
    100             if (0 < cap) {
    101                 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
    102             }
    103             canvas->save();
    104             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
    105                 if (0 < fill) {
    106                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
    107                 }
    108                 canvas->save();
    109                 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
    110                     if (0 < style) {
    111                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
    112                     }
    113 
    114                     SkColor color = 0xff007000;
    115                     this->drawPath(path.fPath, canvas, color, rect,
    116                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
    117                                     gFills[fill].fFill, SK_Scalar1*10);
    118 
    119                     SkPaint rectPaint;
    120                     rectPaint.setColor(SK_ColorBLACK);
    121                     rectPaint.setStyle(SkPaint::kStroke_Style);
    122                     rectPaint.setStrokeWidth(-1);
    123                     rectPaint.setAntiAlias(true);
    124                     canvas->drawRect(rect, rectPaint);
    125 
    126                     SkPaint labelPaint;
    127                     labelPaint.setColor(color);
    128                     labelPaint.setAntiAlias(true);
    129                     labelPaint.setLCDRenderText(true);
    130                     labelPaint.setTextSize(10 * SK_Scalar1);
    131                     canvas->drawText(gStyles[style].fName,
    132                                         strlen(gStyles[style].fName),
    133                                         0, rect.height() + 12 * SK_Scalar1,
    134                                         labelPaint);
    135                     canvas->drawText(gFills[fill].fName,
    136                                         strlen(gFills[fill].fName),
    137                                         0, rect.height() + 24 * SK_Scalar1,
    138                                         labelPaint);
    139                     canvas->drawText(gCaps[cap].fName,
    140                                         strlen(gCaps[cap].fName),
    141                                         0, rect.height() + 36 * SK_Scalar1,
    142                                         labelPaint);
    143                 }
    144                 canvas->restore();
    145             }
    146             canvas->restore();
    147         }
    148         canvas->restore();
    149         canvas->restore();
    150     }
    151 
    152 private:
    153     typedef GM INHERITED;
    154 };
    155 
    156 class QuadClosePathGM : public GM {
    157 public:
    158     QuadClosePathGM() {}
    159 
    160 protected:
    161     SkString onShortName() {
    162         return SkString("quadclosepath");
    163     }
    164 
    165     SkISize onISize() { return make_isize(1240, 390); }
    166 
    167     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
    168                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
    169                   SkPaint::Style style, SkPath::FillType fill,
    170                   SkScalar strokeWidth) {
    171         path.setFillType(fill);
    172         SkPaint paint;
    173         paint.setStrokeCap(cap);
    174         paint.setStrokeWidth(strokeWidth);
    175         paint.setStrokeJoin(join);
    176         paint.setColor(color);
    177         paint.setStyle(style);
    178         canvas->save();
    179         canvas->clipRect(clip);
    180         canvas->drawPath(path, paint);
    181         canvas->restore();
    182     }
    183 
    184     virtual void onDraw(SkCanvas* canvas) {
    185         struct FillAndName {
    186             SkPath::FillType fFill;
    187             const char*      fName;
    188         };
    189         static const FillAndName gFills[] = {
    190             {SkPath::kWinding_FillType, "Winding"},
    191             {SkPath::kEvenOdd_FillType, "Even / Odd"},
    192             {SkPath::kInverseWinding_FillType, "Inverse Winding"},
    193             {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
    194         };
    195         struct StyleAndName {
    196             SkPaint::Style fStyle;
    197             const char*    fName;
    198         };
    199         static const StyleAndName gStyles[] = {
    200             {SkPaint::kFill_Style, "Fill"},
    201             {SkPaint::kStroke_Style, "Stroke"},
    202             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
    203         };
    204         struct CapAndName {
    205             SkPaint::Cap  fCap;
    206             SkPaint::Join fJoin;
    207             const char*   fName;
    208         };
    209         static const CapAndName gCaps[] = {
    210             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
    211             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
    212             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
    213         };
    214         struct PathAndName {
    215             SkPath      fPath;
    216             const char* fName;
    217         };
    218         PathAndName path;
    219         path.fPath.moveTo(25*SK_Scalar1, 10*SK_Scalar1);
    220         path.fPath.quadTo(50*SK_Scalar1, 20*SK_Scalar1,
    221                           75*SK_Scalar1, 10*SK_Scalar1);
    222         path.fPath.close();
    223         path.fName = "moveTo-quad-close";
    224 
    225         SkPaint titlePaint;
    226         titlePaint.setColor(SK_ColorBLACK);
    227         titlePaint.setAntiAlias(true);
    228         titlePaint.setLCDRenderText(true);
    229         titlePaint.setTextSize(15 * SK_Scalar1);
    230         const char title[] = "Quad Closed Drawn Into Rectangle Clips With "
    231                              "Indicated Style, Fill and Linecaps, with stroke width 10";
    232         canvas->drawText(title, strlen(title),
    233                             20 * SK_Scalar1,
    234                             20 * SK_Scalar1,
    235                             titlePaint);
    236 
    237         SkLCGRandom rand;
    238         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
    239         canvas->save();
    240         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
    241         canvas->save();
    242         for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
    243             if (0 < cap) {
    244                 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
    245             }
    246             canvas->save();
    247             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
    248                 if (0 < fill) {
    249                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
    250                 }
    251                 canvas->save();
    252                 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
    253                     if (0 < style) {
    254                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
    255                     }
    256 
    257                     SkColor color = 0xff007000;
    258                     this->drawPath(path.fPath, canvas, color, rect,
    259                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
    260                                     gFills[fill].fFill, SK_Scalar1*10);
    261 
    262                     SkPaint rectPaint;
    263                     rectPaint.setColor(SK_ColorBLACK);
    264                     rectPaint.setStyle(SkPaint::kStroke_Style);
    265                     rectPaint.setStrokeWidth(-1);
    266                     rectPaint.setAntiAlias(true);
    267                     canvas->drawRect(rect, rectPaint);
    268 
    269                     SkPaint labelPaint;
    270                     labelPaint.setColor(color);
    271                     labelPaint.setAntiAlias(true);
    272                     labelPaint.setLCDRenderText(true);
    273                     labelPaint.setTextSize(10 * SK_Scalar1);
    274                     canvas->drawText(gStyles[style].fName,
    275                                         strlen(gStyles[style].fName),
    276                                         0, rect.height() + 12 * SK_Scalar1,
    277                                         labelPaint);
    278                     canvas->drawText(gFills[fill].fName,
    279                                         strlen(gFills[fill].fName),
    280                                         0, rect.height() + 24 * SK_Scalar1,
    281                                         labelPaint);
    282                     canvas->drawText(gCaps[cap].fName,
    283                                         strlen(gCaps[cap].fName),
    284                                         0, rect.height() + 36 * SK_Scalar1,
    285                                         labelPaint);
    286                 }
    287                 canvas->restore();
    288             }
    289             canvas->restore();
    290         }
    291         canvas->restore();
    292         canvas->restore();
    293     }
    294 
    295 private:
    296     typedef GM INHERITED;
    297 };
    298 
    299 //////////////////////////////////////////////////////////////////////////////
    300 
    301 static GM* QuadPathFactory(void*) { return new QuadPathGM; }
    302 static GMRegistry regQuadPath(QuadPathFactory);
    303 
    304 static GM* QuadClosePathFactory(void*) { return new QuadClosePathGM; }
    305 static GMRegistry regQuadClosePath(QuadClosePathFactory);
    306 
    307 }
    308