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