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