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 "sk_tool_utils.h"
      9 #include "SkCanvas.h"
     10 #include "SkPaint.h"
     11 #include "SkPath.h"
     12 #include "SkRandom.h"
     13 
     14 namespace skiagm {
     15 
     16 class EmptyPathGM : public GM {
     17 public:
     18     EmptyPathGM() {}
     19 
     20 protected:
     21     SkString onShortName() {
     22         return SkString("emptypath");
     23     }
     24 
     25     SkISize onISize() { return SkISize::Make(600, 280); }
     26 
     27     void drawEmpty(SkCanvas* canvas,
     28                     SkColor color,
     29                     const SkRect& clip,
     30                     SkPaint::Style style,
     31                     SkPath::FillType fill) {
     32         SkPath path;
     33         path.setFillType(fill);
     34         SkPaint paint;
     35         paint.setColor(color);
     36         paint.setStyle(style);
     37         canvas->save();
     38         canvas->clipRect(clip);
     39         canvas->drawPath(path, paint);
     40         canvas->restore();
     41     }
     42 
     43     virtual void onDraw(SkCanvas* canvas) {
     44         struct FillAndName {
     45             SkPath::FillType fFill;
     46             const char*      fName;
     47         };
     48         constexpr FillAndName gFills[] = {
     49             {SkPath::kWinding_FillType, "Winding"},
     50             {SkPath::kEvenOdd_FillType, "Even / Odd"},
     51             {SkPath::kInverseWinding_FillType, "Inverse Winding"},
     52             {SkPath::kInverseEvenOdd_FillType, "Inverse Even / Odd"},
     53         };
     54         struct StyleAndName {
     55             SkPaint::Style fStyle;
     56             const char*    fName;
     57         };
     58         constexpr StyleAndName gStyles[] = {
     59             {SkPaint::kFill_Style, "Fill"},
     60             {SkPaint::kStroke_Style, "Stroke"},
     61             {SkPaint::kStrokeAndFill_Style, "Stroke And Fill"},
     62         };
     63 
     64         SkPaint titlePaint;
     65         titlePaint.setColor(SK_ColorBLACK);
     66         titlePaint.setAntiAlias(true);
     67         sk_tool_utils::set_portable_typeface(&titlePaint);
     68         titlePaint.setTextSize(15 * SK_Scalar1);
     69         const char title[] = "Empty Paths Drawn Into Rectangle Clips With "
     70                              "Indicated Style and Fill";
     71         canvas->drawString(title,
     72                            20 * SK_Scalar1,
     73                            20 * SK_Scalar1,
     74                            titlePaint);
     75 
     76         SkRandom rand;
     77         SkRect rect = SkRect::MakeWH(100*SK_Scalar1, 30*SK_Scalar1);
     78         int i = 0;
     79         canvas->save();
     80         canvas->translate(10 * SK_Scalar1, 0);
     81         canvas->save();
     82         for (size_t style = 0; style < SK_ARRAY_COUNT(gStyles); ++style) {
     83             for (size_t fill = 0; fill < SK_ARRAY_COUNT(gFills); ++fill) {
     84                 if (0 == i % 4) {
     85                     canvas->restore();
     86                     canvas->translate(0, rect.height() + 40 * SK_Scalar1);
     87                     canvas->save();
     88                 } else {
     89                     canvas->translate(rect.width() + 40 * SK_Scalar1, 0);
     90                 }
     91                 ++i;
     92 
     93 
     94                 SkColor color = rand.nextU();
     95                 color = 0xff000000 | color; // force solid
     96                 color = sk_tool_utils::color_to_565(color);
     97                 this->drawEmpty(canvas, color, rect,
     98                                 gStyles[style].fStyle, gFills[fill].fFill);
     99 
    100                 SkPaint rectPaint;
    101                 rectPaint.setColor(SK_ColorBLACK);
    102                 rectPaint.setStyle(SkPaint::kStroke_Style);
    103                 rectPaint.setStrokeWidth(-1);
    104                 rectPaint.setAntiAlias(true);
    105                 canvas->drawRect(rect, rectPaint);
    106 
    107                 SkPaint labelPaint;
    108                 labelPaint.setColor(color);
    109                 labelPaint.setAntiAlias(true);
    110                 sk_tool_utils::set_portable_typeface(&labelPaint);
    111                 labelPaint.setTextSize(12 * SK_Scalar1);
    112                 canvas->drawString(gStyles[style].fName,
    113                                    0, rect.height() + 15 * SK_Scalar1,
    114                                    labelPaint);
    115                 canvas->drawString(gFills[fill].fName,
    116                                    0, rect.height() + 28 * SK_Scalar1,
    117                                    labelPaint);
    118             }
    119         }
    120         canvas->restore();
    121         canvas->restore();
    122     }
    123 
    124 private:
    125     typedef GM INHERITED;
    126 };
    127 DEF_GM( return new EmptyPathGM; )
    128 
    129 //////////////////////////////////////////////////////////////////////////////
    130 
    131 static void make_path_move(SkPath* path, const SkPoint pts[3]) {
    132     for (int i = 0; i < 3; ++i) {
    133         path->moveTo(pts[i]);
    134     }
    135 }
    136 
    137 static void make_path_move_close(SkPath* path, const SkPoint pts[3]) {
    138     for (int i = 0; i < 3; ++i) {
    139         path->moveTo(pts[i]);
    140         path->close();
    141     }
    142 }
    143 
    144 static void make_path_move_line(SkPath* path, const SkPoint pts[3]) {
    145     for (int i = 0; i < 3; ++i) {
    146         path->moveTo(pts[i]);
    147         path->lineTo(pts[i]);
    148     }
    149 }
    150 
    151 typedef void (*MakePathProc)(SkPath*, const SkPoint pts[3]);
    152 
    153 static void make_path_move_mix(SkPath* path, const SkPoint pts[3]) {
    154     path->moveTo(pts[0]);
    155     path->moveTo(pts[1]); path->close();
    156     path->moveTo(pts[2]); path->lineTo(pts[2]);
    157 }
    158 
    159 class EmptyStrokeGM : public GM {
    160     SkPoint fPts[3];
    161 
    162 public:
    163     EmptyStrokeGM() {
    164         fPts[0].set(40, 40);
    165         fPts[1].set(80, 40);
    166         fPts[2].set(120, 40);
    167     }
    168 
    169 protected:
    170     SkString onShortName() override {
    171         return SkString("emptystroke");
    172     }
    173 
    174     SkISize onISize() override { return SkISize::Make(200, 240); }
    175 
    176     void onDraw(SkCanvas* canvas) override {
    177         const MakePathProc procs[] = {
    178             make_path_move,             // expect red red red
    179             make_path_move_close,       // expect black black black
    180             make_path_move_line,        // expect black black black
    181             make_path_move_mix,         // expect red black black,
    182         };
    183 
    184         SkPaint strokePaint;
    185         strokePaint.setStyle(SkPaint::kStroke_Style);
    186         strokePaint.setStrokeWidth(21);
    187         strokePaint.setStrokeCap(SkPaint::kSquare_Cap);
    188 
    189         SkPaint dotPaint;
    190         dotPaint.setColor(SK_ColorRED);
    191         strokePaint.setStyle(SkPaint::kStroke_Style);
    192         dotPaint.setStrokeWidth(7);
    193 
    194         for (size_t i = 0; i < SK_ARRAY_COUNT(procs); ++i) {
    195             SkPath path;
    196             procs[i](&path, fPts);
    197             canvas->drawPoints(SkCanvas::kPoints_PointMode, 3, fPts, dotPaint);
    198             canvas->drawPath(path, strokePaint);
    199             canvas->translate(0, 40);
    200         }
    201     }
    202 
    203 private:
    204     typedef GM INHERITED;
    205 };
    206 DEF_GM( return new EmptyStrokeGM; )
    207 
    208 }
    209