xref: /aosp_15_r20/external/skia/gm/stringart.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2013 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/gm.h"
9 #include "include/core/SkCanvas.h"
10 #include "include/core/SkPaint.h"
11 #include "include/core/SkPath.h"
12 #include "include/core/SkPoint.h"
13 #include "include/core/SkScalar.h"
14 #include "include/core/SkSize.h"
15 #include "include/core/SkString.h"
16 #include "include/core/SkTypes.h"
17 #include "tools/ToolUtils.h"
18 #include "tools/timer/TimeUtils.h"
19 
20 // Reproduces https://code.google.com/p/chromium/issues/detail?id=279014
21 
22 constexpr int kWidth = 440;
23 constexpr int kHeight = 440;
24 constexpr SkScalar kAngle = 0.305f;
25 constexpr int kMaxNumSteps = 140;
26 
27 // Renders a string art shape.
28 // The particular shape rendered can be controlled by adjusting kAngle, from 0 to 1
29 
30 class StringArtGM : public skiagm::GM {
31 public:
StringArtGM()32     StringArtGM() : fNumSteps(kMaxNumSteps) {}
33 
34 protected:
getName() const35     SkString getName() const override { return SkString("stringart"); }
36 
getISize()37     SkISize getISize() override { return SkISize::Make(kWidth, kHeight); }
38 
onDraw(SkCanvas * canvas)39     void onDraw(SkCanvas* canvas) override {
40         SkScalar angle = kAngle*SK_ScalarPI + SkScalarHalf(SK_ScalarPI);
41         SkScalar size = SkIntToScalar(std::min(kWidth, kHeight));
42         SkPoint center = SkPoint::Make(SkScalarHalf(kWidth), SkScalarHalf(kHeight));
43         SkScalar length = 5;
44         SkScalar step = angle;
45 
46         SkPath path;
47         path.moveTo(center);
48 
49         for (int i = 0; i < fNumSteps && length < (SkScalarHalf(size) - 10.f); ++i) {
50             SkPoint rp = SkPoint::Make(length*SkScalarCos(step) + center.fX,
51                                        length*SkScalarSin(step) + center.fY);
52             path.lineTo(rp);
53             length += angle / SkScalarHalf(SK_ScalarPI);
54             step += angle;
55         }
56 
57         SkPaint paint;
58         paint.setAntiAlias(true);
59         paint.setStyle(SkPaint::kStroke_Style);
60         paint.setColor(ToolUtils::color_to_565(0xFF007700));
61 
62         canvas->drawPath(path, paint);
63     }
64 
onAnimate(double nanos)65     bool onAnimate(double nanos) override {
66         constexpr SkScalar kDesiredDurationSecs = 3.0f;
67 
68         // Make the animation ping-pong back and forth but start in the fully drawn state
69         SkScalar fraction = 1.0f - TimeUtils::Scaled(1e-9 * nanos, 2.0f/kDesiredDurationSecs, 2.0f);
70         if (fraction <= 0.0f) {
71             fraction = -fraction;
72         }
73 
74         SkASSERT(fraction >= 0.0f && fraction <= 1.0f);
75 
76         fNumSteps = (int) (fraction * kMaxNumSteps);
77         return true;
78     }
79 
80 private:
81     int fNumSteps;
82 
83     using INHERITED = GM;
84 };
85 
86 DEF_GM( return new StringArtGM; )
87