| /* |
| * Copyright 2016 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include "gm.h" |
| #include "SkAnimTimer.h" |
| #include "SkPath.h" |
| #include "SkDashPathEffect.h" |
| |
| int dash1[] = { 1, 1 }; |
| int dash2[] = { 1, 3 }; |
| int dash3[] = { 1, 1, 3, 3 }; |
| int dash4[] = { 1, 3, 2, 4 }; |
| |
| struct DashExample { |
| int* pattern; |
| int length; |
| } dashExamples[] = { |
| { dash1, SK_ARRAY_COUNT(dash1) }, |
| { dash2, SK_ARRAY_COUNT(dash2) }, |
| { dash3, SK_ARRAY_COUNT(dash3) }, |
| { dash4, SK_ARRAY_COUNT(dash4) } |
| }; |
| |
| |
| class DashCircleGM : public skiagm::GM { |
| public: |
| DashCircleGM() : fRotation(0) { } |
| |
| protected: |
| SkString onShortName() override { return SkString("dashcircle"); } |
| |
| SkISize onISize() override { return SkISize::Make(900, 1200); } |
| |
| void onDraw(SkCanvas* canvas) override { |
| SkPaint refPaint; |
| refPaint.setAntiAlias(true); |
| refPaint.setColor(0xFFbf3f7f); |
| refPaint.setStyle(SkPaint::kStroke_Style); |
| refPaint.setStrokeWidth(1); |
| const SkScalar radius = 125; |
| SkRect oval = SkRect::MakeLTRB(-radius - 20, -radius - 20, radius + 20, radius + 20); |
| SkPath circle; |
| circle.addCircle(0, 0, radius); |
| SkScalar circumference = radius * SK_ScalarPI * 2; |
| int wedges[] = { 6, 12, 36 }; |
| canvas->translate(radius+20, radius+20); |
| for (int wedge : wedges) { |
| SkScalar arcLength = 360.f / wedge; |
| canvas->save(); |
| for (const DashExample& dashExample : dashExamples) { |
| SkPath refPath; |
| int dashUnits = 0; |
| for (int index = 0; index < dashExample.length; ++index) { |
| dashUnits += dashExample.pattern[index]; |
| } |
| SkScalar unitLength = arcLength / dashUnits; |
| SkScalar angle = 0; |
| for (int index = 0; index < wedge; ++index) { |
| for (int i2 = 0; i2 < dashExample.length; i2 += 2) { |
| SkScalar span = dashExample.pattern[i2] * unitLength; |
| refPath.moveTo(0, 0); |
| refPath.arcTo(oval, angle, span, false); |
| refPath.close(); |
| angle += span + (dashExample.pattern[i2 + 1]) * unitLength; |
| } |
| } |
| canvas->save(); |
| canvas->rotate(fRotation); |
| canvas->drawPath(refPath, refPaint); |
| canvas->restore(); |
| SkPaint p; |
| p.setAntiAlias(true); |
| p.setStyle(SkPaint::kStroke_Style); |
| p.setStrokeWidth(10); |
| SkScalar intervals[4]; |
| int intervalCount = dashExample.length; |
| SkScalar dashLength = circumference / wedge / dashUnits; |
| for (int index = 0; index < dashExample.length; ++index) { |
| intervals[index] = dashExample.pattern[index] * dashLength; |
| } |
| p.setPathEffect(SkDashPathEffect::Make(intervals, intervalCount, 0)); |
| canvas->save(); |
| canvas->rotate(fRotation); |
| canvas->drawPath(circle, p); |
| canvas->restore(); |
| canvas->translate(0, radius * 2 + 50); |
| } |
| canvas->restore(); |
| canvas->translate(radius * 2 + 50, 0); |
| } |
| } |
| |
| bool onAnimate(const SkAnimTimer& timer) override { |
| constexpr SkScalar kDesiredDurationSecs = 100.0f; |
| |
| fRotation = timer.scaled(360.0f/kDesiredDurationSecs, 360.0f); |
| return true; |
| } |
| |
| private: |
| SkScalar fRotation; |
| |
| typedef GM INHERITED; |
| }; |
| |
| DEF_GM(return new DashCircleGM; ) |