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