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