1e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita/*
2e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita * Copyright 2015 Google Inc.
3e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita *
4e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita * Use of this source code is governed by a BSD-style license that can be
5e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita * found in the LICENSE file.
6e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita */
7e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
8e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita#include "gm.h"
9e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
10e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita#include "SkDashPathEffect.h"
11e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita#include "SkPaint.h"
12e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita#include "SkPath.h"
13e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita#include "SkRRect.h"
14e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
15e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalitanamespace skiagm {
16e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
17e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalitaclass ContourStartGM : public GM {
18e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalitapublic:
19e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    ContourStartGM() {
20e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        const SkScalar kMaxDashLen = 100;
21e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        const SkScalar kDashGrowth = 1.2f;
22e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
23e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        SkSTArray<100, SkScalar> intervals;
24e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        for (SkScalar len = 1; len < kMaxDashLen; len *= kDashGrowth) {
25e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            intervals.push_back(len);
26e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            intervals.push_back(len);
27e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        }
28e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
29e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        SkAutoTUnref<SkPathEffect> effect(
30e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkDashPathEffect::Create(intervals.begin(), intervals.count(), 0));
31e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
32e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fDashPaint.setAntiAlias(true);
33e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fDashPaint.setStyle(SkPaint::kStroke_Style);
34e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fDashPaint.setStrokeWidth(6);
35e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fDashPaint.setColor(0xff008000);
36e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fDashPaint.setPathEffect(effect);
37e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
38e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fPointsPaint.setColor(0xff800000);
39e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fPointsPaint.setStrokeWidth(3);
40e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
41e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        fRect = SkRect::MakeLTRB(10, 10, 100, 70);
42e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    }
43e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
44e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalitaprotected:
45e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    SkString onShortName() override {
46e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        return SkString("contour_start");
47e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    }
48e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
49e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    SkISize onISize() override { return SkISize::Make(kImageWidth, kImageHeight); }
50e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
51e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    void onDraw(SkCanvas* canvas) override {
52e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
53e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) {
54e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkPath path;
55e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            path.addRect(rect, dir, startIndex);
56e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            return path;
57e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        });
58e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
59e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) {
60e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkPath path;
61e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            path.addOval(rect, dir, startIndex);
62e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            return path;
63e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        });
64e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
65e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) {
66e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkRRect rrect;
67e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            const SkVector radii[4] = { {15, 15}, {15, 15}, {15, 15}, {15, 15}};
68e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            rrect.setRectRadii(rect, radii);
69e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
70e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkPath path;
71e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            path.addRRect(rrect, dir, startIndex);
72e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            return path;
73e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        });
74e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
75e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) {
76e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkRRect rrect;
77e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            rrect.setRect(rect);
78e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
79e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkPath path;
80e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            path.addRRect(rrect, dir, startIndex);
81e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            return path;
82e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        });
83e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
84e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) {
85e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkRRect rrect;
86e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            rrect.setOval(rect);
87e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
88e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkPath path;
89e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            path.addRRect(rrect, dir, startIndex);
90e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            return path;
91e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        });
92e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
93e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    }
94e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
95e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalitaprivate:
96e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    static const int kImageWidth = 1200;
97e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    static const int kImageHeight = 600;
98e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
99e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    SkPaint fDashPaint, fPointsPaint;
100e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    SkRect  fRect;
101e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
102e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    void drawDirs(SkCanvas* canvas,
103e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita                  SkPath (*makePath)(const SkRect&, SkPath::Direction, unsigned)) const {
104e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        drawOneColumn(canvas, SkPath::kCW_Direction, makePath);
105e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        canvas->translate(kImageWidth / 10, 0);
106e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        drawOneColumn(canvas, SkPath::kCCW_Direction, makePath);
107e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        canvas->translate(kImageWidth / 10, 0);
108e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    }
109e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
110e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    void drawOneColumn(SkCanvas* canvas, SkPath::Direction dir,
111e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita                       SkPath (*makePath)(const SkRect&, SkPath::Direction, unsigned)) const {
112e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        SkAutoCanvasRestore acr(canvas, true);
113e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
114e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        for (unsigned i = 0; i < 8; ++i) {
115e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            const SkPath path = makePath(fRect, dir, i);
116e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            canvas->drawPath(path, fDashPaint);
117e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
118e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            const int n = path.countPoints();
119e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            SkAutoTArray<SkPoint> points(n);
120e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            path.getPoints(points.get(), n);
121e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            canvas->drawPoints(SkCanvas::kPoints_PointMode, n, points.get(), fPointsPaint);
122e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
123e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita            canvas->translate(0, kImageHeight / 8);
124e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita        }
125e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    }
126e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
127e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita    typedef GM INHERITED;
128e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita};
129e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
130e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalitaDEF_GM( return new ContourStartGM(); )
131e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
132e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita} // namespace skiagm
133e55c312929fe5a4e65158d848a4b190e8fbf8c7cfmalita
134