2016-01-19 16:07:49 +00:00
|
|
|
/*
|
|
|
|
* 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"
|
2016-04-08 20:35:14 +00:00
|
|
|
#include "SkAnimTimer.h"
|
2016-01-19 16:07:49 +00:00
|
|
|
#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) }
|
|
|
|
};
|
|
|
|
|
2016-04-08 20:35:14 +00:00
|
|
|
|
|
|
|
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];
|
2016-01-19 16:07:49 +00:00
|
|
|
}
|
2016-04-08 20:35:14 +00:00
|
|
|
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);
|
2016-01-19 16:07:49 +00:00
|
|
|
}
|
2016-04-08 20:35:14 +00:00
|
|
|
canvas->restore();
|
|
|
|
canvas->translate(radius * 2 + 50, 0);
|
2016-01-19 16:07:49 +00:00
|
|
|
}
|
|
|
|
}
|
2016-04-08 20:35:14 +00:00
|
|
|
|
|
|
|
bool onAnimate(const SkAnimTimer& timer) override {
|
|
|
|
static const 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; )
|