1632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com/*
2632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com * Copyright 2012 Google Inc.
3632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com *
4632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com * Use of this source code is governed by a BSD-style license that can be
5632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com * found in the LICENSE file.
6632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com */
7632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "gm.h"
8632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "SkCanvas.h"
9632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "SkPaint.h"
10632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "Sk1DPathEffect.h"
11632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "Sk2DPathEffect.h"
12632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "SkCornerPathEffect.h"
13632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "SkDashPathEffect.h"
14632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com#include "SkDiscretePathEffect.h"
15632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
16632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comnamespace skiagm {
17632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
18632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void compose_pe(SkPaint* paint) {
19632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    SkPathEffect* pe = paint->getPathEffect();
200a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org    SkPathEffect* corner = SkCornerPathEffect::Create(25);
21632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    SkPathEffect* compose;
22632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    if (pe) {
230a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org        compose = SkComposePathEffect::Create(pe, corner);
24632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        corner->unref();
25632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    } else {
26632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        compose = corner;
27632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    }
28632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    paint->setPathEffect(compose)->unref();
29632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
30632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
31632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void hair_pe(SkPaint* paint) {
32632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    paint->setStrokeWidth(0);
33632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
34632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
35632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void hair2_pe(SkPaint* paint) {
36632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    paint->setStrokeWidth(0);
37632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    compose_pe(paint);
38632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
39632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
40632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void stroke_pe(SkPaint* paint) {
41632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    paint->setStrokeWidth(12);
42632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    compose_pe(paint);
43632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
44632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
45632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void dash_pe(SkPaint* paint) {
46632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    SkScalar inter[] = { 20, 10, 10, 10 };
47632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    paint->setStrokeWidth(12);
480a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org    paint->setPathEffect(SkDashPathEffect::Create(inter, SK_ARRAY_COUNT(inter),
490a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org                                                  0))->unref();
50632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    compose_pe(paint);
51632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
52632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
53632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic const int gXY[] = {
54632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4
55632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com};
56632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
57632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void scale(SkPath* path, SkScalar scale) {
58632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    SkMatrix m;
59632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    m.setScale(scale, scale);
60632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    path->transform(m);
61632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
62632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
63632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void one_d_pe(SkPaint* paint) {
64632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    SkPath  path;
65632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1]));
66632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2)
67632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1]));
68632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    path.close();
69632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    path.offset(SkIntToScalar(-6), 0);
701313086ef4d901176e569d1f4b6362250ac02cd7caryclark@google.com    scale(&path, 1.5f);
71ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
720a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org    paint->setPathEffect(SkPath1DPathEffect::Create(path, SkIntToScalar(21), 0,
73632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com                                SkPath1DPathEffect::kRotate_Style))->unref();
74632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    compose_pe(paint);
75632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
76632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
77632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comtypedef void (*PE_Proc)(SkPaint*);
78632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic const PE_Proc gPE[] = { hair_pe, hair2_pe, stroke_pe, dash_pe, one_d_pe };
79632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
80632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void fill_pe(SkPaint* paint) {
81632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    paint->setStyle(SkPaint::kFill_Style);
822880df2609eba09b555ca37be04b6ad89290c765Tom Hudson    paint->setPathEffect(nullptr);
83632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
84632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
85632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void discrete_pe(SkPaint* paint) {
860a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org    paint->setPathEffect(SkDiscretePathEffect::Create(10, 4))->unref();
87632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
88632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
89632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic SkPathEffect* MakeTileEffect() {
90632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    SkMatrix m;
91632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    m.setScale(SkIntToScalar(12), SkIntToScalar(12));
92632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
93632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    SkPath path;
94632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    path.addCircle(0, 0, SkIntToScalar(5));
95ae933ce0ea5fd9d21cb6ef2cee7e729d32690aacrmistry@google.com
960a2bf90dccba3bde188e0386a7f0c60e6dde1ae9commit-bot@chromium.org    return SkPath2DPathEffect::Create(m, path);
97632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
98632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
99632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic void tile_pe(SkPaint* paint) {
100632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    paint->setPathEffect(MakeTileEffect())->unref();
101632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
102632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
103632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic const PE_Proc gPE2[] = { fill_pe, discrete_pe, tile_pe };
104632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
105632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comclass PathEffectGM : public GM {
106632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.compublic:
107632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    PathEffectGM() {}
108632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
109632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comprotected:
110a90c6803865766d28e92091f56f718f5e41fe80fcommit-bot@chromium.org
11136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkString onShortName() override {
112632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        return SkString("patheffect");
113632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    }
114632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
11536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkISize onISize() override { return SkISize::Make(800, 600); }
116632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
11736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onDraw(SkCanvas* canvas) override {
118632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        SkPaint paint;
119632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        paint.setAntiAlias(true);
120632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        paint.setStyle(SkPaint::kStroke_Style);
121632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
122632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        SkPath path;
123632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.moveTo(20, 20);
124632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.lineTo(70, 120);
125632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.lineTo(120, 30);
126632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.lineTo(170, 80);
127632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.lineTo(240, 50);
128632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
129632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        size_t i;
130632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        canvas->save();
131632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        for (i = 0; i < SK_ARRAY_COUNT(gPE); i++) {
132632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com            gPE[i](&paint);
133632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com            canvas->drawPath(path, paint);
134632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com            canvas->translate(0, 75);
135632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        }
136632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        canvas->restore();
137632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
138632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.reset();
139632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        SkRect r = { 0, 0, 250, 120 };
140632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.addOval(r, SkPath::kCW_Direction);
141632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        r.inset(50, 50);
142632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        path.addRect(r, SkPath::kCCW_Direction);
143632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
144632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        canvas->translate(320, 20);
145632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        for (i = 0; i < SK_ARRAY_COUNT(gPE2); i++) {
146632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com            gPE2[i](&paint);
147632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com            canvas->drawPath(path, paint);
148632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com            canvas->translate(0, 160);
149632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com        }
15022f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com
15122f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com        SkIRect rect = SkIRect::MakeXYWH(20, 20, 60, 60);
15222f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com        for (i = 0; i < SK_ARRAY_COUNT(gPE); i++) {
15322f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com            SkPaint p;
15422f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com            p.setAntiAlias(true);
15522f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com            p.setStyle(SkPaint::kFill_Style);
15622f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com            gPE[i](&p);
15722f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com            canvas->drawIRect(rect, p);
15822f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com            canvas->translate(75, 0);
15922f42b71fc7f120e995b6e90e9fca8584438192cbsalomon@google.com        }
160632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    }
161632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
162632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comprivate:
163632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com    typedef GM INHERITED;
164632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com};
165632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
166632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com//////////////////////////////////////////////////////////////////////////////
167632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
168632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic GM* PathEffectFactory(void*) { return new PathEffectGM; }
169632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.comstatic GMRegistry regPathEffect(PathEffectFactory);
170632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com
171632151bc91614fd69481458091fb37b86b7df2cebsalomon@google.com}
172