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 LinePathGM : public GM {
     15 public:
     16     LinePathGM() {}
     17 
     18 protected:
     19     virtual uint32_t onGetFlags() const SK_OVERRIDE {
     20         return kSkipTiled_Flag;
     21     }
     22 
     23     SkString onShortName() {
     24         return SkString("linepath");
     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, 15*SK_Scalar1);
     82         path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1);
     83         path.fName = "moveTo-line";
     84 
     85         SkPaint titlePaint;
     86         titlePaint.setColor(SK_ColorBLACK);
     87         titlePaint.setAntiAlias(true);
     88         titlePaint.setLCDRenderText(true);
     89         titlePaint.setTextSize(15 * SK_Scalar1);
     90         const char title[] = "Line Drawn Into Rectangle Clips With "
     91                              "Indicated Style, Fill and Linecaps, with stroke width 10";
     92         canvas->drawText(title, strlen(title),
     93                             20 * SK_Scalar1,
     94                             20 * SK_Scalar1,
     95                             titlePaint);
     96 
     97         SkLCGRandom rand;
     98         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
     99         canvas->save();
    100         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
    101         canvas->save();
    102         for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
    103             if (0 < cap) {
    104                 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
    105             }
    106             canvas->save();
    107             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
    108                 if (0 < fill) {
    109                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
    110                 }
    111                 canvas->save();
    112                 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
    113                     if (0 < style) {
    114                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
    115                     }
    116 
    117                     SkColor color = 0xff007000;
    118                     this->drawPath(path.fPath, canvas, color, rect,
    119                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
    120                                     gFills[fill].fFill, SK_Scalar1*10);
    121 
    122                     SkPaint rectPaint;
    123                     rectPaint.setColor(SK_ColorBLACK);
    124                     rectPaint.setStyle(SkPaint::kStroke_Style);
    125                     rectPaint.setStrokeWidth(-1);
    126                     rectPaint.setAntiAlias(true);
    127                     canvas->drawRect(rect, rectPaint);
    128 
    129                     SkPaint labelPaint;
    130                     labelPaint.setColor(color);
    131                     labelPaint.setAntiAlias(true);
    132                     labelPaint.setLCDRenderText(true);
    133                     labelPaint.setTextSize(10 * SK_Scalar1);
    134                     canvas->drawText(gStyles[style].fName,
    135                                         strlen(gStyles[style].fName),
    136                                         0, rect.height() + 12 * SK_Scalar1,
    137                                         labelPaint);
    138                     canvas->drawText(gFills[fill].fName,
    139                                         strlen(gFills[fill].fName),
    140                                         0, rect.height() + 24 * SK_Scalar1,
    141                                         labelPaint);
    142                     canvas->drawText(gCaps[cap].fName,
    143                                         strlen(gCaps[cap].fName),
    144                                         0, rect.height() + 36 * SK_Scalar1,
    145                                         labelPaint);
    146                 }
    147                 canvas->restore();
    148             }
    149             canvas->restore();
    150         }
    151         canvas->restore();
    152         canvas->restore();
    153     }
    154 
    155 private:
    156     typedef GM INHERITED;
    157 };
    158 
    159 class LineClosePathGM : public GM {
    160 public:
    161     LineClosePathGM() {}
    162 
    163 protected:
    164     SkString onShortName() {
    165         return SkString("lineclosepath");
    166     }
    167 
    168     SkISize onISize() { return SkISize::Make(1240, 390); }
    169 
    170     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
    171                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
    172                   SkPaint::Style style, SkPath::FillType fill,
    173                   SkScalar strokeWidth) {
    174         path.setFillType(fill);
    175         SkPaint paint;
    176         paint.setStrokeCap(cap);
    177         paint.setStrokeWidth(strokeWidth);
    178         paint.setStrokeJoin(join);
    179         paint.setColor(color);
    180         paint.setStyle(style);
    181         canvas->save();
    182         canvas->clipRect(clip);
    183         canvas->drawPath(path, paint);
    184         canvas->restore();
    185     }
    186 
    187     virtual void onDraw(SkCanvas* canvas) {
    188         struct FillAndName {
    189             SkPath::FillType fFill;
    190             const char*      fName;
    191         };
    192         static const FillAndName gFills[] = {
    193             {SkPath::kWinding_FillType, "Winding"},
    194             {SkPath::kEvenOdd_FillType, "Even / Odd"},
    195             {SkPath::kInverseWinding_FillType, "Inverse Winding"},
    196             {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
    197         };
    198         struct StyleAndName {
    199             SkPaint::Style fStyle;
    200             const char*    fName;
    201         };
    202         static const StyleAndName gStyles[] = {
    203             {SkPaint::kFill_Style, "Fill"},
    204             {SkPaint::kStroke_Style, "Stroke"},
    205             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
    206         };
    207         struct CapAndName {
    208             SkPaint::Cap  fCap;
    209             SkPaint::Join fJoin;
    210             const char*   fName;
    211         };
    212         static const CapAndName gCaps[] = {
    213             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
    214             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
    215             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
    216         };
    217         struct PathAndName {
    218             SkPath      fPath;
    219             const char* fName;
    220         };
    221         PathAndName path;
    222         path.fPath.moveTo(25*SK_Scalar1, 15*SK_Scalar1);
    223         path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1);
    224         path.fPath.close();
    225         path.fName = "moveTo-line-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[] = "Line 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         SkLCGRandom 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* LinePathFactory(void*) { return new LinePathGM; }
    304 static GMRegistry regLinePath(LinePathFactory);
    305 
    306 static GM* LineClosePathFactory(void*) { return new LineClosePathGM; }
    307 static GMRegistry regLineClosePath(LineClosePathFactory);
    308 
    309 }
    310