| reed@google.com | 8d850be | 2012-07-13 15:55:15 +0000 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2012 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 |  | 
 | 8 | #include "gm.h" | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 9 | #include "SkAnimTimer.h" | 
| reed@google.com | 8d850be | 2012-07-13 15:55:15 +0000 | [diff] [blame] | 10 | #include "SkCanvas.h" | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 11 | #include "SkDashPathEffect.h" | 
| reed@google.com | 8d850be | 2012-07-13 15:55:15 +0000 | [diff] [blame] | 12 | #include "SkPath.h" | 
 | 13 | #include "SkParsePath.h" | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 14 | #include "SkTArray.h" | 
 | 15 | #include "SkTrimPathEffect.h" | 
| reed@google.com | 8d850be | 2012-07-13 15:55:15 +0000 | [diff] [blame] | 16 |  | 
| Ben Wagner | f08d1d0 | 2018-06-18 15:11:00 -0400 | [diff] [blame] | 17 | #include <utility> | 
 | 18 |  | 
| reed@google.com | 8d850be | 2012-07-13 15:55:15 +0000 | [diff] [blame] | 19 | /* | 
 | 20 |  *  Inspired by http://code.google.com/p/chromium/issues/detail?id=112145 | 
 | 21 |  */ | 
| reed | a439334 | 2016-03-18 11:22:57 -0700 | [diff] [blame] | 22 | static void flower(SkCanvas* canvas, const SkPath& path, SkScalar intervals[2], | 
 | 23 |                    SkPaint::Join join) { | 
 | 24 |     SkPaint paint; | 
 | 25 |     paint.setAntiAlias(true); | 
 | 26 |     paint.setStyle(SkPaint::kStroke_Style); | 
 | 27 |     paint.setStrokeJoin(join); | 
 | 28 |     paint.setStrokeWidth(42); | 
 | 29 |     canvas->drawPath(path, paint); | 
| caryclark | 6df8e34 | 2015-02-23 12:47:03 -0800 | [diff] [blame] | 30 |  | 
| reed | a439334 | 2016-03-18 11:22:57 -0700 | [diff] [blame] | 31 |     paint.setColor(SK_ColorRED); | 
 | 32 |     paint.setStrokeWidth(21); | 
 | 33 |     paint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0)); | 
 | 34 |     canvas->drawPath(path, paint); | 
| caryclark | 6df8e34 | 2015-02-23 12:47:03 -0800 | [diff] [blame] | 35 |  | 
| reed | a439334 | 2016-03-18 11:22:57 -0700 | [diff] [blame] | 36 |     paint.setColor(SK_ColorGREEN); | 
 | 37 |     paint.setPathEffect(nullptr); | 
 | 38 |     paint.setStrokeWidth(0); | 
 | 39 |     canvas->drawPath(path, paint); | 
| halcanary | 2a24338 | 2015-09-09 08:16:41 -0700 | [diff] [blame] | 40 | } | 
| reed@google.com | 8d850be | 2012-07-13 15:55:15 +0000 | [diff] [blame] | 41 |  | 
| reed | 6dc14aa | 2016-04-11 07:46:38 -0700 | [diff] [blame] | 42 | DEF_SIMPLE_GM(dashcubics, canvas, 865, 750) { | 
| reed@google.com | 8d850be | 2012-07-13 15:55:15 +0000 | [diff] [blame] | 43 |         SkPath path; | 
 | 44 |         const char* d = "M 337,98 C 250,141 250,212 250,212 C 250,212 250,212 250,212" | 
 | 45 |         "C 250,212 250,212 250,212 C 250,212 250,141 163,98 C 156,195 217,231 217,231" | 
 | 46 |         "C 217,231 217,231 217,231 C 217,231 217,231 217,231 C 217,231 156,195 75,250" | 
 | 47 |         "C 156,305 217,269 217,269 C 217,269 217,269 217,269 C 217,269 217,269 217,269" | 
 | 48 |         "C 217,269 156,305 163,402 C 250,359 250,288 250,288 C 250,288 250,288 250,288" | 
 | 49 |         "C 250,288 250,288 250,288 C 250,288 250,359 338,402 C 345,305 283,269 283,269" | 
 | 50 |         "C 283,269 283,269 283,269 C 283,269 283,269 283,269 C 283,269 345,305 425,250" | 
 | 51 |         "C 344,195 283,231 283,231 C 283,231 283,231 283,231 C 283,231 283,231 283,231" | 
 | 52 |         "C 283,231 344,195 338,98"; | 
 | 53 |  | 
 | 54 |         SkParsePath::FromSVGString(d, &path); | 
| caryclark | 6df8e34 | 2015-02-23 12:47:03 -0800 | [diff] [blame] | 55 |             canvas->translate(-35.f, -55.f); | 
 | 56 |         for (int x = 0; x < 2; ++x) { | 
 | 57 |             for (int y = 0; y < 2; ++y) { | 
 | 58 |                 canvas->save(); | 
 | 59 |                 canvas->translate(x * 430.f, y * 355.f); | 
 | 60 |                 SkScalar intervals[] = { 5 + (x ? 0 : 0.0001f + 0.0001f), 10 }; | 
 | 61 |                 flower(canvas, path, intervals, y ? SkPaint::kDefault_Join : SkPaint::kRound_Join); | 
 | 62 |                 canvas->restore(); | 
 | 63 |             } | 
 | 64 |         } | 
| halcanary | 2a24338 | 2015-09-09 08:16:41 -0700 | [diff] [blame] | 65 | } | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 66 |  | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 67 | class TrimGM : public skiagm::GM { | 
 | 68 | public: | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 69 |     TrimGM() { | 
 | 70 |         SkAssertResult(SkParsePath::FromSVGString( | 
 | 71 |             "M   0,100 C  10, 50 190, 50 200,100" | 
 | 72 |             "M 200,100 C 210,150 390,150 400,100" | 
 | 73 |             "M 400,100 C 390, 50 210, 50 200,100" | 
 | 74 |             "M 200,100 C 190,150  10,150   0,100", | 
 | 75 |             &fPaths.push_back())); | 
 | 76 |  | 
 | 77 |         SkAssertResult(SkParsePath::FromSVGString( | 
 | 78 |             "M   0, 75 L 200, 75" | 
 | 79 |             "M 200, 91 L 200, 91" | 
 | 80 |             "M 200,108 L 200,108" | 
 | 81 |             "M 200,125 L 400,125", | 
 | 82 |             &fPaths.push_back())); | 
 | 83 |  | 
 | 84 |         SkAssertResult(SkParsePath::FromSVGString( | 
 | 85 |             "M   0,100 L  50, 50" | 
 | 86 |             "M  50, 50 L 150,150" | 
 | 87 |             "M 150,150 L 250, 50" | 
 | 88 |             "M 250, 50 L 350,150" | 
 | 89 |             "M 350,150 L 400,100", | 
 | 90 |             &fPaths.push_back())); | 
 | 91 |  | 
 | 92 |     } | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 93 |  | 
 | 94 | protected: | 
 | 95 |     SkString onShortName() override { return SkString("trimpatheffect"); } | 
 | 96 |  | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 97 |     SkISize onISize() override { | 
 | 98 |         return SkISize::Make(1400, 1000); | 
 | 99 |     } | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 100 |  | 
 | 101 |     void onDraw(SkCanvas* canvas) override { | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 102 |         static constexpr SkSize kCellSize = { 440, 150 }; | 
 | 103 |         static constexpr SkScalar kOffsets[][2] = { | 
 | 104 |             { -0.33f, -0.66f }, | 
 | 105 |             {  0    ,  1    }, | 
 | 106 |             {  0    ,  0.25f}, | 
 | 107 |             {  0.25f,  0.75f}, | 
 | 108 |             {  0.75f,  1    }, | 
 | 109 |             {  1    ,  0.75f}, | 
 | 110 |         }; | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 111 |  | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 112 |         SkPaint hairlinePaint; | 
 | 113 |         hairlinePaint.setAntiAlias(true); | 
 | 114 |         hairlinePaint.setStyle(SkPaint::kStroke_Style); | 
 | 115 |         hairlinePaint.setStrokeCap(SkPaint::kRound_Cap); | 
 | 116 |         hairlinePaint.setStrokeWidth(2); | 
 | 117 |         SkPaint normalPaint = hairlinePaint; | 
 | 118 |         normalPaint.setStrokeWidth(10); | 
 | 119 |         normalPaint.setColor(0x8000ff00); | 
 | 120 |         SkPaint invertedPaint = normalPaint; | 
 | 121 |         invertedPaint.setColor(0x80ff0000); | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 122 |  | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 123 |         for (const auto& offset : kOffsets) { | 
 | 124 |             auto start = offset[0] + fOffset, | 
 | 125 |                  stop  = offset[1] + fOffset; | 
 | 126 |  | 
 | 127 |             auto normalMode   = SkTrimPathEffect::Mode::kNormal, | 
 | 128 |                  invertedMode = SkTrimPathEffect::Mode::kInverted; | 
 | 129 |             if (fOffset) { | 
 | 130 |                 start -= SkScalarFloorToScalar(start); | 
 | 131 |                 stop  -= SkScalarFloorToScalar(stop); | 
 | 132 |                 if (start > stop) { | 
| Ben Wagner | f08d1d0 | 2018-06-18 15:11:00 -0400 | [diff] [blame] | 133 |                     using std::swap; | 
 | 134 |                     swap(start, stop); | 
 | 135 |                     swap(normalMode, invertedMode); | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 136 |                 } | 
 | 137 |             } | 
 | 138 |  | 
 | 139 |             normalPaint.setPathEffect(SkTrimPathEffect::Make(start, stop, normalMode)); | 
 | 140 |             invertedPaint.setPathEffect(SkTrimPathEffect::Make(start, stop, invertedMode)); | 
 | 141 |  | 
 | 142 |             { | 
 | 143 |                 SkAutoCanvasRestore acr(canvas, true); | 
 | 144 |                 for (const auto& path : fPaths) { | 
 | 145 |                     canvas->drawPath(path, normalPaint); | 
 | 146 |                     canvas->drawPath(path, invertedPaint); | 
 | 147 |                     canvas->drawPath(path, hairlinePaint); | 
 | 148 |                     canvas->translate(kCellSize.width(), 0); | 
 | 149 |                 } | 
 | 150 |             } | 
 | 151 |  | 
 | 152 |             canvas->translate(0, kCellSize.height()); | 
 | 153 |         } | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 154 |     } | 
 | 155 |  | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 156 |     bool onAnimate(const SkAnimTimer& t) override { | 
 | 157 |         fOffset = t.msec() / 2000.0f; | 
 | 158 |         fOffset -= floorf(fOffset); | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 159 |         return true; | 
 | 160 |     } | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 161 |  | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 162 | private: | 
| Florin Malita | 827af66 | 2018-03-09 16:08:58 -0500 | [diff] [blame] | 163 |     SkTArray<SkPath> fPaths; | 
 | 164 |     SkScalar         fOffset = 0; | 
 | 165 |  | 
| Mike Reed | 4123223 | 2018-03-07 17:02:47 -0500 | [diff] [blame] | 166 |     typedef skiagm::GM INHERITED; | 
 | 167 | }; | 
 | 168 | DEF_GM(return new TrimGM;) | 
 | 169 |  |