OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "sk_tool_utils.h" | 8 #include "sk_tool_utils.h" |
9 #include "SampleCode.h" | 9 #include "SampleCode.h" |
10 #include "SkView.h" | 10 #include "SkView.h" |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
| 12 #include "SkGeometry.h" |
12 #include "SkPathMeasure.h" | 13 #include "SkPathMeasure.h" |
13 #include "SkRandom.h" | 14 #include "SkRandom.h" |
14 #include "SkRRect.h" | 15 #include "SkRRect.h" |
15 #include "SkColorPriv.h" | 16 #include "SkColorPriv.h" |
16 #include "SkStrokerPriv.h" | 17 #include "SkStrokerPriv.h" |
17 #include "SkSurface.h" | 18 #include "SkSurface.h" |
18 | 19 |
19 static bool hittest(const SkPoint& target, SkScalar x, SkScalar y) { | 20 static bool hittest(const SkPoint& target, SkScalar x, SkScalar y) { |
20 const SkScalar TOL = 7; | 21 const SkScalar TOL = 7; |
21 return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL; | 22 return SkPoint::Distance(target, SkPoint::Make(x, y)) <= TOL; |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 StrokeTypeButton fTextButton; | 116 StrokeTypeButton fTextButton; |
116 SkString fText; | 117 SkString fText; |
117 SkScalar fTextSize; | 118 SkScalar fTextSize; |
118 SkScalar fWeight; | 119 SkScalar fWeight; |
119 SkScalar fWidth, fDWidth; | 120 SkScalar fWidth, fDWidth; |
120 SkScalar fWidthScale; | 121 SkScalar fWidthScale; |
121 int fW, fH, fZoom; | 122 int fW, fH, fZoom; |
122 bool fAnimate; | 123 bool fAnimate; |
123 bool fDrawRibs; | 124 bool fDrawRibs; |
124 bool fDrawTangents; | 125 bool fDrawTangents; |
| 126 bool fDrawTDivs; |
125 #ifdef SK_DEBUG | 127 #ifdef SK_DEBUG |
126 #define kStrokerErrorMin 0.001f | 128 #define kStrokerErrorMin 0.001f |
127 #define kStrokerErrorMax 5 | 129 #define kStrokerErrorMax 5 |
128 #endif | 130 #endif |
129 #define kWidthMin 1 | 131 #define kWidthMin 1 |
130 #define kWidthMax 100 | 132 #define kWidthMax 100 |
131 public: | 133 public: |
132 QuadStrokerView() { | 134 QuadStrokerView() { |
133 this->setBGColor(SK_ColorLTGRAY); | 135 this->setBGColor(SK_ColorLTGRAY); |
134 | 136 |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 } | 283 } |
282 | 284 |
283 void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width, | 285 void draw_ribs(SkCanvas* canvas, const SkPath& path, SkScalar width, |
284 SkColor color) { | 286 SkColor color) { |
285 const SkScalar radius = width / 2; | 287 const SkScalar radius = width / 2; |
286 | 288 |
287 SkPathMeasure meas(path, false); | 289 SkPathMeasure meas(path, false); |
288 SkScalar total = meas.getLength(); | 290 SkScalar total = meas.getLength(); |
289 | 291 |
290 SkScalar delta = 8; | 292 SkScalar delta = 8; |
291 SkPaint paint; | 293 SkPaint paint, labelP; |
292 paint.setColor(color); | 294 paint.setColor(color); |
293 | 295 labelP.setColor(color & 0xff5f9f5f); |
294 SkPoint pos, tan; | 296 SkPoint pos, tan; |
| 297 int index = 0; |
295 for (SkScalar dist = 0; dist <= total; dist += delta) { | 298 for (SkScalar dist = 0; dist <= total; dist += delta) { |
296 if (meas.getPosTan(dist, &pos, &tan)) { | 299 if (meas.getPosTan(dist, &pos, &tan)) { |
297 tan.scale(radius); | 300 tan.scale(radius); |
298 tan.rotateCCW(); | 301 tan.rotateCCW(); |
299 canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), | 302 canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), |
300 pos.x() - tan.x(), pos.y() - tan.y(), paint); | 303 pos.x() - tan.x(), pos.y() - tan.y(), paint); |
| 304 if (0 == index % 10) { |
| 305 SkString label; |
| 306 label.appendS32(index); |
| 307 SkRect dot = SkRect::MakeXYWH(pos.x() - 2, pos.y() - 2, 4, 4
); |
| 308 canvas->drawRect(dot, labelP); |
| 309 canvas->drawText(label.c_str(), label.size(), |
| 310 pos.x() - tan.x() * 1.25f, pos.y() - tan.y() * 1.25f, la
belP); |
| 311 } |
| 312 } |
| 313 ++index; |
| 314 } |
| 315 } |
| 316 |
| 317 void draw_t_divs(SkCanvas* canvas, const SkPath& path, SkScalar width, SkCol
or color) { |
| 318 const SkScalar radius = width / 2; |
| 319 SkPaint paint; |
| 320 paint.setColor(color); |
| 321 SkPathMeasure meas(path, false); |
| 322 SkScalar total = meas.getLength(); |
| 323 SkScalar delta = 8; |
| 324 int ribs = 0; |
| 325 for (SkScalar dist = 0; dist <= total; dist += delta) { |
| 326 ++ribs; |
| 327 } |
| 328 SkPath::RawIter iter(path); |
| 329 SkPoint pts[4]; |
| 330 if (SkPath::kMove_Verb != iter.next(pts)) { |
| 331 SkASSERT(0); |
| 332 return; |
| 333 } |
| 334 SkPath::Verb verb = iter.next(pts); |
| 335 SkASSERT(SkPath::kLine_Verb <= verb && verb <= SkPath::kCubic_Verb); |
| 336 SkPoint pos, tan; |
| 337 for (int index = 0; index < ribs; ++index) { |
| 338 SkScalar t = (SkScalar) index / ribs; |
| 339 switch (verb) { |
| 340 case SkPath::kLine_Verb: |
| 341 tan = pts[1] - pts[0]; |
| 342 pos = pts[0]; |
| 343 pos.fX += tan.fX * t; |
| 344 pos.fY += tan.fY * t; |
| 345 break; |
| 346 case SkPath::kQuad_Verb: |
| 347 pos = SkEvalQuadAt(pts, t); |
| 348 tan = SkEvalQuadTangentAt(pts, t); |
| 349 break; |
| 350 case SkPath::kConic_Verb: { |
| 351 SkConic conic(pts, iter.conicWeight()); |
| 352 pos = conic.evalAt(t); |
| 353 tan = conic.evalTangentAt(t); |
| 354 } break; |
| 355 case SkPath::kCubic_Verb: |
| 356 SkEvalCubicAt(pts, t, &pos, &tan, nullptr); |
| 357 break; |
| 358 default: |
| 359 SkASSERT(0); |
| 360 return; |
| 361 } |
| 362 tan.setLength(radius); |
| 363 tan.rotateCCW(); |
| 364 canvas->drawLine(pos.x() + tan.x(), pos.y() + tan.y(), |
| 365 pos.x() - tan.x(), pos.y() - tan.y(), paint); |
| 366 if (0 == index % 10) { |
| 367 SkString label; |
| 368 label.appendS32(index); |
| 369 canvas->drawText(label.c_str(), label.size(), |
| 370 pos.x() + tan.x() * 1.25f, pos.y() + tan.y() * 1.25f, paint)
; |
301 } | 371 } |
302 } | 372 } |
303 } | 373 } |
304 | 374 |
305 void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width, SkSca
lar scale, | 375 void draw_stroke(SkCanvas* canvas, const SkPath& path, SkScalar width, SkSca
lar scale, |
306 bool drawText) { | 376 bool drawText) { |
307 if (path.isEmpty()) { | 377 if (path.isEmpty()) { |
308 return; | 378 return; |
309 } | 379 } |
310 SkRect bounds = path.getBounds(); | 380 SkRect bounds = path.getBounds(); |
(...skipping 25 matching lines...) Expand all Loading... |
336 } else { | 406 } else { |
337 scaled = path; | 407 scaled = path; |
338 } | 408 } |
339 canvas->drawPath(scaled, paint); | 409 canvas->drawPath(scaled, paint); |
340 draw_points(canvas, scaled, SKELETON_COLOR, true); | 410 draw_points(canvas, scaled, SKELETON_COLOR, true); |
341 | 411 |
342 if (fDrawRibs) { | 412 if (fDrawRibs) { |
343 draw_ribs(canvas, scaled, width, 0xFF00FF00); | 413 draw_ribs(canvas, scaled, width, 0xFF00FF00); |
344 } | 414 } |
345 | 415 |
| 416 if (fDrawTDivs) { |
| 417 draw_t_divs(canvas, scaled, width, 0xFF3F3F00); |
| 418 } |
| 419 |
346 SkPath fill; | 420 SkPath fill; |
347 | 421 |
348 SkPaint p; | 422 SkPaint p; |
349 p.setStyle(SkPaint::kStroke_Style); | 423 p.setStyle(SkPaint::kStroke_Style); |
350 if (drawText) { | 424 if (drawText) { |
351 p.setStrokeWidth(width * scale * scale); | 425 p.setStrokeWidth(width * scale * scale); |
352 } else { | 426 } else { |
353 p.setStrokeWidth(width); | 427 p.setStrokeWidth(width); |
354 } | 428 } |
355 p.getFillPath(path, &fill); | 429 p.getFillPath(path, &fill); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 paint.setTextSize(11.0f); | 495 paint.setTextSize(11.0f); |
422 paint.setStyle(SkPaint::kFill_Style); | 496 paint.setStyle(SkPaint::kFill_Style); |
423 canvas->drawText(label.c_str(), label.size(), bounds.fLeft + 5, yPos - 5
, paint); | 497 canvas->drawText(label.c_str(), label.size(), bounds.fLeft + 5, yPos - 5
, paint); |
424 paint.setTextSize(13.0f); | 498 paint.setTextSize(13.0f); |
425 canvas->drawText(name, strlen(name), bounds.fLeft, bounds.bottom() + 11,
paint); | 499 canvas->drawText(name, strlen(name), bounds.fLeft, bounds.bottom() + 11,
paint); |
426 } | 500 } |
427 | 501 |
428 void setForGeometry() { | 502 void setForGeometry() { |
429 fDrawRibs = true; | 503 fDrawRibs = true; |
430 fDrawTangents = true; | 504 fDrawTangents = true; |
| 505 fDrawTDivs = false; |
431 fWidthScale = 1; | 506 fWidthScale = 1; |
432 } | 507 } |
433 | 508 |
434 void setForText() { | 509 void setForText() { |
435 fDrawRibs = fDrawTangents = false; | 510 fDrawRibs = fDrawTangents = fDrawTDivs = false; |
436 fWidthScale = 0.002f; | 511 fWidthScale = 0.002f; |
437 } | 512 } |
438 | 513 |
| 514 void setForSingles() { |
| 515 setForGeometry(); |
| 516 fDrawTDivs = true; |
| 517 } |
| 518 |
439 void setAsNeeded() { | 519 void setAsNeeded() { |
440 if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabl
ed | 520 if (fConicButton.fEnabled || fCubicButton.fEnabled || fQuadButton.fEnabl
ed) { |
441 || fRRectButton.fEnabled || fCircleButton.fEnabled) { | 521 setForSingles(); |
| 522 } else if (fRRectButton.fEnabled || fCircleButton.fEnabled) { |
442 setForGeometry(); | 523 setForGeometry(); |
443 } else { | 524 } else { |
444 setForText(); | 525 setForText(); |
445 } | 526 } |
446 } | 527 } |
447 | 528 |
448 void onDrawContent(SkCanvas* canvas) override { | 529 void onDrawContent(SkCanvas* canvas) override { |
449 SkPath path; | 530 SkPath path; |
450 SkScalar width = fWidth; | 531 SkScalar width = fWidth; |
451 | 532 |
452 if (fCubicButton.fEnabled) { | 533 if (fCubicButton.fEnabled) { |
453 path.moveTo(fPts[0]); | 534 path.moveTo(fPts[0]); |
454 path.cubicTo(fPts[1], fPts[2], fPts[3]); | 535 path.cubicTo(fPts[1], fPts[2], fPts[3]); |
455 setForGeometry(); | 536 setForSingles(); |
456 draw_stroke(canvas, path, width, 950, false); | 537 draw_stroke(canvas, path, width, 950, false); |
457 } | 538 } |
458 | 539 |
459 if (fConicButton.fEnabled) { | 540 if (fConicButton.fEnabled) { |
| 541 path.reset(); |
460 path.moveTo(fPts[4]); | 542 path.moveTo(fPts[4]); |
461 path.conicTo(fPts[5], fPts[6], fWeight); | 543 path.conicTo(fPts[5], fPts[6], fWeight); |
462 setForGeometry(); | 544 setForSingles(); |
463 draw_stroke(canvas, path, width, 950, false); | 545 draw_stroke(canvas, path, width, 950, false); |
464 } | 546 } |
465 | 547 |
466 if (fQuadButton.fEnabled) { | 548 if (fQuadButton.fEnabled) { |
467 path.reset(); | 549 path.reset(); |
468 path.moveTo(fPts[7]); | 550 path.moveTo(fPts[7]); |
469 path.quadTo(fPts[8], fPts[9]); | 551 path.quadTo(fPts[8], fPts[9]); |
470 setForGeometry(); | 552 setForSingles(); |
471 draw_stroke(canvas, path, width, 950, false); | 553 draw_stroke(canvas, path, width, 950, false); |
472 } | 554 } |
473 | 555 |
474 if (fRRectButton.fEnabled) { | 556 if (fRRectButton.fEnabled) { |
475 SkScalar rad = 32; | 557 SkScalar rad = 32; |
476 SkRect r; | 558 SkRect r; |
477 r.set(&fPts[10], 2); | 559 r.set(&fPts[10], 2); |
478 path.reset(); | 560 path.reset(); |
479 SkRRect rr; | 561 SkRRect rr; |
480 rr.setRectXY(r, rad, rad); | 562 rr.setRectXY(r, rad, rad); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 } | 710 } |
629 | 711 |
630 private: | 712 private: |
631 typedef SkView INHERITED; | 713 typedef SkView INHERITED; |
632 }; | 714 }; |
633 | 715 |
634 /////////////////////////////////////////////////////////////////////////////// | 716 /////////////////////////////////////////////////////////////////////////////// |
635 | 717 |
636 static SkView* F2() { return new QuadStrokerView; } | 718 static SkView* F2() { return new QuadStrokerView; } |
637 static SkViewRegister gR2(F2); | 719 static SkViewRegister gR2(F2); |
OLD | NEW |