xref: /aosp_15_r20/external/skia/tools/viewer/ClockSlide.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 #include "include/core/SkCanvas.h"
8 #include "include/core/SkPath.h"
9 #include "include/core/SkRRect.h"
10 #include "include/private/base/SkAssert.h"
11 #include "src/base/SkRandom.h"
12 #include "tools/viewer/Slide.h"
13 
14 #include <chrono>
15 #include <ctime>
16 
17 // Implementation in C++ of Mozilla Canvas2D benchmark Canvas Clock Test
18 // See https://code.google.com/p/skia/issues/detail?id=1626
19 
20 #define USE_PATH 1
21 
22 class ClockSlide : public Slide {
23 public:
ClockSlide()24     ClockSlide() { fName = "Clock"; }
25 
draw(SkCanvas * canvas)26     void draw(SkCanvas* canvas) override {
27         SkPaint paintFill;
28         SkPaint paintStroke;
29         SkPath  path;
30 
31         canvas->save();
32         canvas->translate(150, 150);
33         canvas->scale(0.4f, 0.4f);
34         canvas->rotate(-180.f/2.f);
35 
36         paintFill.setAntiAlias(true);
37         paintFill.setColor(SK_ColorBLACK);
38         paintStroke.setAntiAlias(true);
39         paintStroke.setStyle(SkPaint::kStroke_Style);
40         paintStroke.setColor(SK_ColorBLACK);
41         paintStroke.setStrokeWidth(8);
42         paintStroke.setStrokeCap(SkPaint::kRound_Cap);
43 
44         // Hour marks
45         SkRect rect;
46 #ifndef USE_PATH
47         rect = SkRect::MakeLTRB(200-4, -4, 240+4, 4);
48         SkRRect rrect;
49         SkVector radii[4] = {{4,4}, {4,4}, {4,4}, {4,4}};
50         rrect.setRectRadii(rect, radii);
51 #endif
52         canvas->save();
53         for (int i=0;i<12;i++){
54             canvas->rotate(180.f/6.f);
55 #ifdef USE_PATH
56             path.reset();
57             path.moveTo(200,0);
58             path.lineTo(240,0);
59             canvas->drawPath(path, paintStroke);
60 #else
61             canvas->drawRRect(rrect, paintFill);
62 #endif
63         }
64         canvas->restore();
65 
66         // Minute marks
67         canvas->save();
68 #ifdef USE_PATH
69         paintStroke.setStrokeWidth(5);
70 #else
71         rect = SkRect::MakeLTRB(231.5f, -2.5f, 242.5, 2.5f);
72         radii[0] = SkPoint::Make(2.5f,2.5f);
73         radii[1] = SkPoint::Make(2.5f,2.5f);
74         radii[2] = SkPoint::Make(2.5f,2.5f);
75         radii[3] = SkPoint::Make(2.5f,2.5f);
76         rrect.setRectRadii(rect, radii);
77 #endif
78         for (int i=0;i<60;i++){
79             if (i%5 == 0) {
80                 canvas->rotate(180.f/30.f);
81                 continue;
82             }
83 #ifdef USE_PATH
84             path.reset();
85             path.moveTo(234,0);
86             path.lineTo(240,0);
87             canvas->drawPath(path, paintStroke);
88 #else
89             canvas->drawRRect(rrect, paintFill);
90 #endif
91             canvas->rotate(180.f/30.f);
92         }
93         canvas->restore();
94 
95         const auto  time  = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
96         const auto* ltime = std::localtime(&time);  // not thread safe, but should be ok for slides
97 
98         paintFill.setColor(SK_ColorBLACK);
99 
100         // Write hours
101         canvas->save();
102         canvas->rotate(ltime->tm_hour * (180.f / 6) +
103                        ltime->tm_min  * (180.f / 360) +
104                        ltime->tm_sec  * (180.f / 21600));
105 #ifdef USE_PATH
106         paintStroke.setStrokeWidth(14);
107         path.reset();
108         path.moveTo(-20,0);
109         path.lineTo(80,0);
110         canvas->drawPath(path, paintStroke);
111 #else
112         rect = SkRect::MakeLTRB(-20-7, -7, 80+7, 7);
113         radii[0] = SkPoint::Make(7,7);
114         radii[1] = SkPoint::Make(7,7);
115         radii[2] = SkPoint::Make(7,7);
116         radii[3] = SkPoint::Make(7,7);
117         rrect.setRectRadii(rect, radii);
118         canvas->drawRRect(rrect, paintFill);
119 #endif
120         canvas->restore();
121 
122         // Write minutes
123         canvas->save();
124         canvas->rotate(ltime->tm_min * (180.f / 30) +
125                        ltime->tm_sec * (180.f / 1800));
126 #ifdef USE_PATH
127         paintStroke.setStrokeWidth(10);
128         path.reset();
129         path.moveTo(-56,0);
130         path.lineTo(224,0);
131         canvas->drawPath(path, paintStroke);
132 #else
133         rect = SkRect::MakeLTRB(-56-5, -5, 224+5, 5);
134         radii[0] = SkPoint::Make(5,5);
135         radii[1] = SkPoint::Make(5,5);
136         radii[2] = SkPoint::Make(5,5);
137         radii[3] = SkPoint::Make(5,5);
138         rrect.setRectRadii(rect, radii);
139         canvas->drawRRect(rrect, paintFill);
140 #endif
141         canvas->restore();
142 
143         // Write seconds
144         canvas->save();
145         canvas->rotate(ltime->tm_sec * (180.f / 30));
146         paintFill.setColor(0xffd40000);
147         paintStroke.setColor(0xffd40000);
148         paintStroke.setStrokeWidth(6);
149 #ifdef USE_PATH
150         path.reset();
151         path.moveTo(-60,0);
152         path.lineTo(166,0);
153         canvas->drawPath(path, paintStroke);
154 #else
155         rect = SkRect::MakeLTRB(-60-3, -3, 166+3, 3);
156         radii[0] = SkPoint::Make(3,3);
157         radii[1] = SkPoint::Make(3,3);
158         radii[2] = SkPoint::Make(3,3);
159         radii[3] = SkPoint::Make(3,3);
160         rrect.setRectRadii(rect, radii);
161         canvas->drawRRect(rrect, paintFill);
162 #endif
163         rect = SkRect::MakeLTRB(-20, -20, 20, 20);
164 #ifdef USE_PATH
165         path.reset();
166         path.arcTo(rect, 0, 0, false);
167         path.addOval(rect, SkPathDirection::kCCW);
168         path.arcTo(rect, 360, 0, true);
169         canvas->drawPath(path, paintFill);
170 #else
171         canvas->drawOval(rect, paintFill);
172 #endif
173         rect = SkRect::MakeLTRB(-20+190, -20, 20+190, 20);
174 #ifdef USE_PATH
175         path.reset();
176         path.arcTo(rect, 0, 0, false);
177         path.addOval(rect, SkPathDirection::kCCW);
178         path.arcTo(rect, 360, 0, true);
179         canvas->drawPath(path, paintStroke);
180 #else
181         canvas->drawOval(rect, paintStroke);
182 #endif
183         paintFill.setColor(0xff505050);
184 #ifdef USE_PATH
185         rect = SkRect::MakeLTRB(-6, -6, 6, 6);
186         path.arcTo(rect, 0, 0, false);
187         path.addOval(rect, SkPathDirection::kCCW);
188         path.arcTo(rect, 360, 0, true);
189         canvas->drawPath(path, paintFill);
190 #else
191         canvas->drawOval(rect, paintFill);
192         rect = SkRect::MakeLTRB(-6, -6, 6, 6);
193         canvas->drawOval(rect, paintFill);
194 #endif
195         canvas->restore();
196 
197         paintStroke.setStrokeWidth(18);
198         paintStroke.setColor(0xff325FA2);
199         rect = SkRect::MakeLTRB(-284, -284, 284, 284);
200 #ifdef USE_PATH
201         path.reset();
202         path.arcTo(rect, 0, 0, false);
203         path.addOval(rect, SkPathDirection::kCCW);
204         path.arcTo(rect, 360, 0, true);
205         canvas->drawPath(path, paintStroke);
206 #else
207         canvas->drawOval(rect, paintStroke);
208 #endif
209 
210         canvas->restore();
211     }
212 
animate(double)213     bool animate(double /*nanos*/) override { return true; }
214 };
215 
216 DEF_SLIDE( return new ClockSlide(); )
217