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