mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +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 "SampleCode.h" |
| 9 | #include "SkView.h" |
| 10 | #include "SkCanvas.h" |
| 11 | #include "SkRandom.h" |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 12 | #include "SkRRect.h" |
| 13 | #include "SkColorPriv.h" |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 14 | |
| 15 | static void rotateAbout(SkCanvas* canvas, SkScalar degrees, |
| 16 | SkScalar cx, SkScalar cy) { |
| 17 | canvas->translate(cx, cy); |
| 18 | canvas->rotate(degrees); |
| 19 | canvas->translate(-cx, -cy); |
| 20 | } |
| 21 | |
| 22 | class RotateCirclesView : public SampleView { |
| 23 | public: |
| 24 | RotateCirclesView() { |
| 25 | this->setBGColor(SK_ColorLTGRAY); |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 26 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 27 | fAngle = 0; |
| 28 | } |
| 29 | |
| 30 | protected: |
| 31 | // overrides from SkEventSink |
| 32 | virtual bool onQuery(SkEvent* evt) { |
| 33 | if (SampleCode::TitleQ(*evt)) { |
| 34 | SampleCode::TitleR(evt, "RotateCircles"); |
| 35 | return true; |
| 36 | } |
| 37 | return this->INHERITED::onQuery(evt); |
| 38 | } |
| 39 | |
| 40 | virtual void onDrawContent(SkCanvas* canvas) { |
| 41 | SkRandom rand; |
| 42 | SkPaint paint; |
| 43 | paint.setAntiAlias(true); |
| 44 | paint.setStrokeWidth(20); |
| 45 | |
| 46 | SkScalar cx = 240; |
| 47 | SkScalar cy = 240; |
| 48 | SkScalar DX = 240 * 2; |
| 49 | SkColor color = 0; |
| 50 | |
| 51 | float scale = 1; |
| 52 | float sign = 0.3f; |
| 53 | for (SkScalar rad = 200; rad >= 20; rad -= 15) { |
| 54 | sign = -sign; |
| 55 | scale += 0.2f; |
| 56 | |
| 57 | paint.setColor(rand.nextU()); |
| 58 | paint.setAlpha(0xFF); |
| 59 | color = ~color; |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 60 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 61 | paint.setStyle(SkPaint::kFill_Style); |
| 62 | |
| 63 | canvas->save(); |
| 64 | rotateAbout(canvas, fAngle * scale * sign, cx, cy); |
| 65 | canvas->drawCircle(cx, cy, rad, paint); |
| 66 | canvas->restore(); |
| 67 | |
| 68 | paint.setStyle(SkPaint::kStroke_Style); |
| 69 | paint.setStrokeWidth(rad*2); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 70 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 71 | canvas->save(); |
| 72 | rotateAbout(canvas, fAngle * scale * sign, cx + DX, cy); |
| 73 | canvas->drawCircle(cx + DX, cy, 10, paint); |
| 74 | canvas->restore(); |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 75 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 76 | canvas->save(); |
| 77 | rotateAbout(canvas, fAngle * scale * sign, cx + DX, cy + DX); |
| 78 | canvas->drawCircle(cx + DX, cy + DX, 10, paint); |
| 79 | canvas->restore(); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 80 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 81 | } |
skia.committer@gmail.com | 15ed90f | 2012-12-23 02:01:31 +0000 | [diff] [blame] | 82 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 83 | fAngle = (fAngle + 1) % 360; |
| 84 | this->inval(NULL); |
| 85 | } |
| 86 | |
| 87 | private: |
| 88 | int fAngle; |
| 89 | typedef SkView INHERITED; |
| 90 | }; |
| 91 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 92 | class TestCirclesView : public SampleView { |
| 93 | public: |
| 94 | TestCirclesView() { |
| 95 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 96 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 97 | protected: |
| 98 | virtual bool onQuery(SkEvent* evt) SK_OVERRIDE { |
| 99 | if (SampleCode::TitleQ(*evt)) { |
| 100 | SampleCode::TitleR(evt, "RotateCircles2"); |
| 101 | return true; |
| 102 | } |
| 103 | return this->INHERITED::onQuery(evt); |
| 104 | } |
| 105 | |
| 106 | void draw_real_circle(SkCanvas* canvas, SkScalar radius) { |
| 107 | int w = SkScalarCeilToInt(radius * 2); |
| 108 | int h = w; |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 109 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 110 | SkBitmap bm; |
| 111 | bm.setConfig(SkBitmap::kARGB_8888_Config, w, h); |
| 112 | bm.allocPixels(); |
| 113 | bm.eraseColor(0); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 114 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 115 | SkAutoLockPixels alp(bm); |
| 116 | |
| 117 | SkScalar cx = radius; |
| 118 | SkScalar cy = radius; |
| 119 | for (int y = 0; y < h; y += 1) { |
| 120 | for (int x = 0; x < w; x += 1) { |
| 121 | float d = sqrtf((x - cx)*(x - cx) + (y - cy)*(y - cy)); |
| 122 | if (d <= radius) { |
| 123 | *bm.getAddr32(x, y) = SkPackARGB32(0xFF, 0, 0, 0); |
| 124 | } |
| 125 | } |
| 126 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 127 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 128 | canvas->drawBitmap(bm, 0, 0, NULL); |
| 129 | } |
| 130 | |
| 131 | virtual void onDrawContent(SkCanvas* canvas) { |
| 132 | SkScalar radius = 256; |
| 133 | canvas->translate(10, 10); |
| 134 | |
| 135 | draw_real_circle(canvas, radius); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 136 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 137 | SkPaint paint; |
| 138 | paint.setAntiAlias(true); |
| 139 | |
| 140 | paint.setColor(0x80FF0000); |
| 141 | canvas->drawCircle(radius, radius, radius, paint); |
| 142 | |
| 143 | paint.setStyle(SkPaint::kStroke_Style); |
| 144 | paint.setStrokeWidth(radius); |
| 145 | paint.setColor(0x8000FF00); |
| 146 | canvas->drawCircle(radius, radius, radius/2, paint); |
| 147 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 148 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 149 | private: |
| 150 | typedef SkView INHERITED; |
| 151 | }; |
| 152 | |
| 153 | static bool hittest(const SkPoint& target, SkScalar x, SkScalar y) { |
| 154 | const SkScalar TOL = 7; |
| 155 | return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL; |
| 156 | } |
| 157 | |
| 158 | static int getOnCurvePoints(const SkPath& path, SkPoint storage[]) { |
| 159 | SkPath::RawIter iter(path); |
| 160 | SkPoint pts[4]; |
| 161 | SkPath::Verb verb; |
| 162 | |
| 163 | int count = 0; |
| 164 | while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
| 165 | switch (verb) { |
| 166 | case SkPath::kMove_Verb: |
| 167 | case SkPath::kLine_Verb: |
| 168 | case SkPath::kQuad_Verb: |
| 169 | case SkPath::kCubic_Verb: |
| 170 | storage[count++] = pts[0]; |
| 171 | break; |
| 172 | default: |
| 173 | break; |
| 174 | } |
| 175 | } |
| 176 | return count; |
| 177 | } |
| 178 | |
| 179 | #include "SkPathMeasure.h" |
| 180 | |
| 181 | class TestStrokeView : public SampleView { |
| 182 | enum { |
| 183 | SKELETON_COLOR = 0xFF0000FF, |
| 184 | WIREFRAME_COLOR = 0x80FF0000 |
| 185 | }; |
| 186 | |
| 187 | enum { |
| 188 | kCount = 9 |
| 189 | }; |
| 190 | SkPoint fPts[kCount]; |
| 191 | SkScalar fWidth, fDWidth; |
| 192 | public: |
| 193 | TestStrokeView() { |
| 194 | this->setBGColor(SK_ColorLTGRAY); |
| 195 | |
| 196 | fPts[0].set(50, 200); |
| 197 | fPts[1].set(50, 100); |
| 198 | fPts[2].set(150, 50); |
| 199 | fPts[3].set(300, 50); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 200 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 201 | fPts[4].set(350, 200); |
| 202 | fPts[5].set(350, 100); |
| 203 | fPts[6].set(450, 50); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 204 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 205 | fPts[7].set(200, 200); |
| 206 | fPts[8].set(400, 400); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 207 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 208 | fWidth = 50; |
| 209 | fDWidth = 0.25f; |
| 210 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 211 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 212 | protected: |
| 213 | virtual bool onQuery(SkEvent* evt) SK_OVERRIDE { |
| 214 | if (SampleCode::TitleQ(*evt)) { |
| 215 | SampleCode::TitleR(evt, "RotateCircles3"); |
| 216 | return true; |
| 217 | } |
| 218 | return this->INHERITED::onQuery(evt); |
| 219 | } |
| 220 | |
| 221 | void draw_points(SkCanvas* canvas, const SkPath& path, SkColor color, |
| 222 | bool show_lines) { |
| 223 | SkPaint paint; |
| 224 | paint.setColor(color); |
| 225 | paint.setAlpha(0x80); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 226 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 227 | int n = path.countPoints(); |
| 228 | SkAutoSTArray<32, SkPoint> pts(n); |
| 229 | if (show_lines) { |
| 230 | path.getPoints(pts.get(), n); |
| 231 | canvas->drawPoints(SkCanvas::kPolygon_PointMode, n, pts.get(), paint); |
| 232 | } else { |
| 233 | n = getOnCurvePoints(path, pts.get()); |
| 234 | } |
| 235 | paint.setStrokeWidth(5); |
| 236 | canvas->drawPoints(SkCanvas::kPoints_PointMode, n, pts.get(), paint); |
| 237 | } |
| 238 | |
| 239 | void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width, |
| 240 | SkColor color) { |
| 241 | const SkScalar radius = width / 2; |
| 242 | |
| 243 | SkPathMeasure meas(path, false); |
| 244 | SkScalar total = meas.getLength(); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 245 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 246 | SkScalar delta = 8; |
| 247 | SkPaint paint; |
| 248 | paint.setColor(color); |
| 249 | |
| 250 | SkPoint pos, tan; |
| 251 | for (SkScalar dist = 0; dist <= total; dist += delta) { |
reed@google.com | 140d728 | 2013-01-07 20:25:04 +0000 | [diff] [blame] | 252 | if (meas.getPosTan(dist, &pos, &tan)) { |
| 253 | tan.scale(radius); |
| 254 | tan.rotateCCW(); |
| 255 | canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), |
| 256 | pos.x() - tan.x(), pos.y() - tan.y(), paint); |
| 257 | } |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 258 | } |
| 259 | } |
| 260 | |
| 261 | void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width) { |
| 262 | SkPaint paint; |
| 263 | paint.setAntiAlias(true); |
| 264 | paint.setStyle(SkPaint::kStroke_Style); |
| 265 | |
| 266 | paint.setColor(SKELETON_COLOR); |
| 267 | canvas->drawPath(path, paint); |
| 268 | draw_points(canvas, path, SKELETON_COLOR, true); |
| 269 | |
| 270 | draw_ribs(canvas, path, width, 0xFF00FF00); |
| 271 | |
| 272 | SkPath fill; |
| 273 | |
| 274 | SkPaint p; |
| 275 | p.setStyle(SkPaint::kStroke_Style); |
| 276 | p.setStrokeWidth(width); |
| 277 | p.getFillPath(path, &fill); |
| 278 | |
| 279 | paint.setColor(WIREFRAME_COLOR); |
| 280 | canvas->drawPath(fill, paint); |
| 281 | draw_points(canvas, fill, WIREFRAME_COLOR, false); |
| 282 | } |
| 283 | |
| 284 | virtual void onDrawContent(SkCanvas* canvas) { |
| 285 | SkPath path; |
| 286 | SkScalar width = fWidth; |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 287 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 288 | path.moveTo(fPts[0]); |
| 289 | path.cubicTo(fPts[1], fPts[2], fPts[3]); |
| 290 | draw_stroke(canvas, path, width); |
| 291 | |
| 292 | path.reset(); |
| 293 | path.moveTo(fPts[4]); |
| 294 | path.quadTo(fPts[5], fPts[6]); |
| 295 | draw_stroke(canvas, path, width); |
| 296 | |
| 297 | SkScalar rad = 32; |
| 298 | SkRect r; |
| 299 | r.set(&fPts[7], 2); |
| 300 | path.reset(); |
| 301 | SkRRect rr; |
| 302 | rr.setRectXY(r, rad, rad); |
| 303 | path.addRRect(rr); |
| 304 | draw_stroke(canvas, path, width); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 305 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 306 | path.reset(); |
| 307 | SkRRect rr2; |
| 308 | rr.inset(width/2, width/2, &rr2); |
| 309 | path.addRRect(rr2, SkPath::kCCW_Direction); |
| 310 | rr.inset(-width/2, -width/2, &rr2); |
| 311 | path.addRRect(rr2, SkPath::kCW_Direction); |
| 312 | SkPaint paint; |
| 313 | paint.setAntiAlias(true); |
| 314 | paint.setColor(0x40FF8844); |
| 315 | canvas->drawPath(path, paint); |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 316 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 317 | fWidth += fDWidth; |
| 318 | if (fDWidth > 0 && fWidth > 100) { |
| 319 | fDWidth = -fDWidth; |
| 320 | } else if (fDWidth < 0 && fWidth < 10) { |
| 321 | fDWidth = -fDWidth; |
| 322 | } |
| 323 | this->inval(NULL); |
| 324 | } |
| 325 | |
| 326 | class MyClick : public Click { |
| 327 | public: |
| 328 | int fIndex; |
| 329 | MyClick(SkView* target, int index) : Click(target), fIndex(index) {} |
| 330 | }; |
| 331 | |
reed@google.com | 4d5c26d | 2013-01-08 16:17:50 +0000 | [diff] [blame] | 332 | virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y, |
| 333 | unsigned modi) SK_OVERRIDE { |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 334 | for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); ++i) { |
| 335 | if (hittest(fPts[i], x, y)) { |
| 336 | return new MyClick(this, i); |
| 337 | } |
| 338 | } |
reed@google.com | 4d5c26d | 2013-01-08 16:17:50 +0000 | [diff] [blame] | 339 | return this->INHERITED::onFindClickHandler(x, y, modi); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 340 | } |
skia.committer@gmail.com | 2157983 | 2012-12-25 02:01:27 +0000 | [diff] [blame] | 341 | |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 342 | virtual bool onClick(Click* click) { |
| 343 | int index = ((MyClick*)click)->fIndex; |
jvanverth@google.com | 9c81bd5 | 2013-01-03 14:46:41 +0000 | [diff] [blame] | 344 | fPts[index].offset(SkIntToScalar(click->fICurr.fX - click->fIPrev.fX), |
| 345 | SkIntToScalar(click->fICurr.fY - click->fIPrev.fY)); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 346 | this->inval(NULL); |
| 347 | return true; |
| 348 | } |
| 349 | |
| 350 | private: |
| 351 | typedef SkView INHERITED; |
| 352 | }; |
| 353 | |
| 354 | /////////////////////////////////////////////////////////////////////////////// |
| 355 | |
mike@reedtribe.org | b563709 | 2012-12-22 20:53:59 +0000 | [diff] [blame] | 356 | static SkView* F0() { return new RotateCirclesView; } |
| 357 | static SkViewRegister gR0(F0); |
mike@reedtribe.org | 61490fa | 2012-12-24 14:38:46 +0000 | [diff] [blame] | 358 | static SkView* F1() { return new TestCirclesView; } |
| 359 | static SkViewRegister gR1(F1); |
| 360 | static SkView* F2() { return new TestStrokeView; } |
| 361 | static SkViewRegister gR2(F2); |