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         sk_tool_utils::set_portable_typeface(&titlePaint);
     89         titlePaint.setLCDRenderText(true);
     90         titlePaint.setTextSize(15 * SK_Scalar1);
     91         const char title[] = "Line 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                     sk_tool_utils::set_portable_typeface(&labelPaint);
    134                     labelPaint.setLCDRenderText(true);
    135                     labelPaint.setTextSize(10 * SK_Scalar1);
    136                     canvas->drawText(gStyles[style].fName,
    137                                         strlen(gStyles[style].fName),
    138                                         0, rect.height() + 12 * SK_Scalar1,
    139                                         labelPaint);
    140                     canvas->drawText(gFills[fill].fName,
    141                                         strlen(gFills[fill].fName),
    142                                         0, rect.height() + 24 * SK_Scalar1,
    143                                         labelPaint);
    144                     canvas->drawText(gCaps[cap].fName,
    145                                         strlen(gCaps[cap].fName),
    146                                         0, rect.height() + 36 * SK_Scalar1,
    147                                         labelPaint);
    148                 }
    149                 canvas->restore();
    150             }
    151             canvas->restore();
    152         }
    153         canvas->restore();
    154         canvas->restore();
    155     }
    156 
    157 private:
    158     typedef GM INHERITED;
    159 };
    160 
    161 class LineClosePathGM : public GM {
    162 public:
    163     LineClosePathGM() {}
    164 
    165 protected:
    166     SkString onShortName() {
    167         return SkString("lineclosepath");
    168     }
    169 
    170     SkISize onISize() { return SkISize::Make(1240, 390); }
    171 
    172     void drawPath(SkPath& path,SkCanvas* canvas,SkColor color,
    173                   const SkRect& clip,SkPaint::Cap cap, SkPaint::Join join,
    174                   SkPaint::Style style, SkPath::FillType fill,
    175                   SkScalar strokeWidth) {
    176         path.setFillType(fill);
    177         SkPaint paint;
    178         paint.setStrokeCap(cap);
    179         paint.setStrokeWidth(strokeWidth);
    180         paint.setStrokeJoin(join);
    181         paint.setColor(color);
    182         paint.setStyle(style);
    183         canvas->save();
    184         canvas->clipRect(clip);
    185         canvas->drawPath(path, paint);
    186         canvas->restore();
    187     }
    188 
    189     virtual void onDraw(SkCanvas* canvas) {
    190         struct FillAndName {
    191             SkPath::FillType fFill;
    192             const char*      fName;
    193         };
    194         static const FillAndName gFills[] = {
    195             {SkPath::kWinding_FillType, "Winding"},
    196             {SkPath::kEvenOdd_FillType, "Even / Odd"},
    197             {SkPath::kInverseWinding_FillType, "Inverse Winding"},
    198             {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
    199         };
    200         struct StyleAndName {
    201             SkPaint::Style fStyle;
    202             const char*    fName;
    203         };
    204         static const StyleAndName gStyles[] = {
    205             {SkPaint::kFill_Style, "Fill"},
    206             {SkPaint::kStroke_Style, "Stroke"},
    207             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
    208         };
    209         struct CapAndName {
    210             SkPaint::Cap  fCap;
    211             SkPaint::Join fJoin;
    212             const char*   fName;
    213         };
    214         static const CapAndName gCaps[] = {
    215             {SkPaint::kButt_Cap, SkPaint::kBevel_Join, "Butt"},
    216             {SkPaint::kRound_Cap, SkPaint::kRound_Join, "Round"},
    217             {SkPaint::kSquare_Cap, SkPaint::kBevel_Join, "Square"}
    218         };
    219         struct PathAndName {
    220             SkPath      fPath;
    221             const char* fName;
    222         };
    223         PathAndName path;
    224         path.fPath.moveTo(25*SK_Scalar1, 15*SK_Scalar1);
    225         path.fPath.lineTo(75*SK_Scalar1, 15*SK_Scalar1);
    226         path.fPath.close();
    227         path.fName = "moveTo-line-close";
    228 
    229         SkPaint titlePaint;
    230         titlePaint.setColor(SK_ColorBLACK);
    231         titlePaint.setAntiAlias(true);
    232         sk_tool_utils::set_portable_typeface(&titlePaint);
    233         titlePaint.setLCDRenderText(true);
    234         titlePaint.setTextSize(15 * SK_Scalar1);
    235         const char title[] = "Line Closed Drawn Into Rectangle Clips With "
    236                              "Indicated Style, Fill and Linecaps, with stroke width 10";
    237         canvas->drawText(title, strlen(title),
    238                             20 * SK_Scalar1,
    239                             20 * SK_Scalar1,
    240                             titlePaint);
    241 
    242         SkLCGRandom rand;
    243         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
    244         canvas->save();
    245         canvas->translate(10 * SK_Scalar1, 30 * SK_Scalar1);
    246         canvas->save();
    247         for (size_t cap = 0; cap < SK_ARRAY_COUNT(gCaps); ++cap) {
    248             if (0 < cap) {
    249                 canvas->translate((rect.width() + 40 * SK_Scalar1) * SK_ARRAY_COUNT(gStyles), 0);
    250             }
    251             canvas->save();
    252             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
    253                 if (0 < fill) {
    254                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
    255                 }
    256                 canvas->save();
    257                 for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
    258                     if (0 < style) {
    259                         canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
    260                     }
    261 
    262                     SkColor color = 0xff007000;
    263                     this->drawPath(path.fPath, canvas, color, rect,
    264                                     gCaps[cap].fCap, gCaps[cap].fJoin, gStyles[style].fStyle,
    265                                     gFills[fill].fFill, SK_Scalar1*10);
    266 
    267                     SkPaint rectPaint;
    268                     rectPaint.setColor(SK_ColorBLACK);
    269                     rectPaint.setStyle(SkPaint::kStroke_Style);
    270                     rectPaint.setStrokeWidth(-1);
    271                     rectPaint.setAntiAlias(true);
    272                     canvas->drawRect(rect, rectPaint);
    273 
    274                     SkPaint labelPaint;
    275                     labelPaint.setColor(color);
    276                     labelPaint.setAntiAlias(true);
    277                     sk_tool_utils::set_portable_typeface(&labelPaint);
    278                     labelPaint.setLCDRenderText(true);
    279                     labelPaint.setTextSize(10 * SK_Scalar1);
    280                     canvas->drawText(gStyles[style].fName,
    281                                         strlen(gStyles[style].fName),
    282                                         0, rect.height() + 12 * SK_Scalar1,
    283                                         labelPaint);
    284                     canvas->drawText(gFills[fill].fName,
    285                                         strlen(gFills[fill].fName),
    286                                         0, rect.height() + 24 * SK_Scalar1,
    287                                         labelPaint);
    288                     canvas->drawText(gCaps[cap].fName,
    289                                         strlen(gCaps[cap].fName),
    290                                         0, rect.height() + 36 * SK_Scalar1,
    291                                         labelPaint);
    292                 }
    293                 canvas->restore();
    294             }
    295             canvas->restore();
    296         }
    297         canvas->restore();
    298         canvas->restore();
    299     }
    300 
    301 private:
    302     typedef GM INHERITED;
    303 };
    304 
    305 //////////////////////////////////////////////////////////////////////////////
    306 
    307 static GM* LinePathFactory(void*) { return new LinePathGM; }
    308 static GMRegistry regLinePath(LinePathFactory);
    309 
    310 static GM* LineClosePathFactory(void*) { return new LineClosePathGM; }
    311 static GMRegistry regLineClosePath(LineClosePathFactory);
    312 
    313 }
    314