150d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
250d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov/*
350d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov * Copyright 2014 Google Inc.
450d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov *
550d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov * Use of this source code is governed by a BSD-style license that can be
650d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov * found in the LICENSE file.
750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov */
850d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
950d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov#include "gm.h"
10b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkGradientShader.h"
11b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h"
12b3c9d1c33caf325aada244204215eb790c228c12dandov
13b3c9d1c33caf325aada244204215eb790c228c12dandovstatic SkShader* make_shader() {
14b3c9d1c33caf325aada244204215eb790c228c12dandov    const SkColor colors[] = {
15b3c9d1c33caf325aada244204215eb790c228c12dandov        SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, SK_ColorMAGENTA, SK_ColorBLUE,
16b3c9d1c33caf325aada244204215eb790c228c12dandov        SK_ColorYELLOW,
17b3c9d1c33caf325aada244204215eb790c228c12dandov    };
18b3c9d1c33caf325aada244204215eb790c228c12dandov    const SkPoint pts[] = { { 100.f / 4.f, 0.f }, { 3.f * 100.f / 4.f, 100.f } };
19b3c9d1c33caf325aada244204215eb790c228c12dandov
20b3c9d1c33caf325aada244204215eb790c228c12dandov    return SkGradientShader::CreateLinear(pts, colors, NULL, SK_ARRAY_COUNT(colors),
21b3c9d1c33caf325aada244204215eb790c228c12dandov                                          SkShader::kMirror_TileMode);
22b3c9d1c33caf325aada244204215eb790c228c12dandov}
2350d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
24b3c9d1c33caf325aada244204215eb790c228c12dandovstatic void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
25ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov    //draw control points
26963137b75c0a1fe91f35e9826742f36309f5e65ddandov    SkPaint paint;
27b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint bottom[SkPatchUtils::kNumPtsCubic];
28b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getBottomCubic(cubics, bottom);
29b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint top[SkPatchUtils::kNumPtsCubic];
30b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getTopCubic(cubics, top);
31b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint left[SkPatchUtils::kNumPtsCubic];
32b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getLeftCubic(cubics, left);
33b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint right[SkPatchUtils::kNumPtsCubic];
34b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getRightCubic(cubics, right);
35ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
36963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorBLACK);
37b3c9d1c33caf325aada244204215eb790c228c12dandov    paint.setStrokeWidth(0.5f);
38ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov    SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
39963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
40b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
41963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
42963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
43963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
44ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
45b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
46b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
47b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
48ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
49963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setStrokeWidth(2);
50ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
51963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorRED);
52963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
53ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
54963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorBLUE);
55b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
56ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
57963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorCYAN);
58b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
59ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
60963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorYELLOW);
61b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
62ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
63963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorGREEN);
64b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
65ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov}
66ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
6750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandovnamespace skiagm {
6850d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov/**
69b3c9d1c33caf325aada244204215eb790c228c12dandov * This GM draws a cubics coons patch using the specialized call SkCanvas::drawPatch.
7050d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov */
7150d715476b1d3a00fb43c13e34a80ea0a01d32bfdandovclass SkPatchGM : public GM {
72ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
7350d715476b1d3a00fb43c13e34a80ea0a01d32bfdandovpublic:
7450d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    SkPatchGM() {
7550d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov        this->setBGColor(0xFFFFFFFF);
7650d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    }
7750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
7850d715476b1d3a00fb43c13e34a80ea0a01d32bfdandovprotected:
7950d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    virtual SkString onShortName() SK_OVERRIDE {
8050d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov        return SkString("patch_primitive");
8150d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    }
8250d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
8350d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    virtual SkISize onISize() SK_OVERRIDE {
8450d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov        return SkISize::Make(800, 800);
8550d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    }
8650d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
8750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    virtual uint32_t onGetFlags() const SK_OVERRIDE {
88963137b75c0a1fe91f35e9826742f36309f5e65ddandov        return kSkipTiled_Flag;
8950d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    }
90cc03adb90901d226e8b0252a187b19a68fabcc42dandov
9150d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
92cc03adb90901d226e8b0252a187b19a68fabcc42dandov
9350d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov        SkPaint paint;
94963137b75c0a1fe91f35e9826742f36309f5e65ddandov
95963137b75c0a1fe91f35e9826742f36309f5e65ddandov        // The order of the colors and points is clockwise starting at upper-left corner.
96b3c9d1c33caf325aada244204215eb790c228c12dandov        const SkPoint cubics[SkPatchUtils::kNumCtrlPts] = {
97963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //top points
98b3c9d1c33caf325aada244204215eb790c228c12dandov            {100,100},{150,50},{250,150}, {300,100},
99963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //right points
100b3c9d1c33caf325aada244204215eb790c228c12dandov            {250, 150},{350,250},
101963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //bottom points
102b3c9d1c33caf325aada244204215eb790c228c12dandov            {300,300},{250,250},{150,350},{100,300},
103963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //left points
104b3c9d1c33caf325aada244204215eb790c228c12dandov            {50,250},{150,150}
10550d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov        };
10650d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
107b3c9d1c33caf325aada244204215eb790c228c12dandov        const SkColor colors[SkPatchUtils::kNumCorners] = {
108b3c9d1c33caf325aada244204215eb790c228c12dandov            SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
109b3c9d1c33caf325aada244204215eb790c228c12dandov        };
110b3c9d1c33caf325aada244204215eb790c228c12dandov        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
111b3c9d1c33caf325aada244204215eb790c228c12dandov            {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}}
112b3c9d1c33caf325aada244204215eb790c228c12dandov        ;
113963137b75c0a1fe91f35e9826742f36309f5e65ddandov
114b3c9d1c33caf325aada244204215eb790c228c12dandov        const SkXfermode::Mode modes[] = {
115b3c9d1c33caf325aada244204215eb790c228c12dandov            SkXfermode::kSrc_Mode,
116b3c9d1c33caf325aada244204215eb790c228c12dandov            SkXfermode::kDst_Mode,
117b3c9d1c33caf325aada244204215eb790c228c12dandov            SkXfermode::kModulate_Mode,
118b3c9d1c33caf325aada244204215eb790c228c12dandov        };
119963137b75c0a1fe91f35e9826742f36309f5e65ddandov
120b3c9d1c33caf325aada244204215eb790c228c12dandov        SkAutoTUnref<SkShader> shader(make_shader());
121b3c9d1c33caf325aada244204215eb790c228c12dandov
122b3c9d1c33caf325aada244204215eb790c228c12dandov        canvas->save();
123b3c9d1c33caf325aada244204215eb790c228c12dandov        for (int y = 0; y < 3; y++) {
124b3c9d1c33caf325aada244204215eb790c228c12dandov            SkAutoTUnref<SkXfermode> xfer(SkXfermode::Create(modes[y]));
125b3c9d1c33caf325aada244204215eb790c228c12dandov
126b3c9d1c33caf325aada244204215eb790c228c12dandov            for (int x = 0; x < 4; x++) {
127b3c9d1c33caf325aada244204215eb790c228c12dandov                canvas->save();
128b3c9d1c33caf325aada244204215eb790c228c12dandov                canvas->translate(x * 350.0f, y * 350.0f);
129b3c9d1c33caf325aada244204215eb790c228c12dandov                switch (x) {
130b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 0:
131b3c9d1c33caf325aada244204215eb790c228c12dandov                        canvas->drawPatch(cubics, NULL, NULL, xfer, paint);
132b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
133b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 1:
134b3c9d1c33caf325aada244204215eb790c228c12dandov                        canvas->drawPatch(cubics, colors, NULL, xfer, paint);
135b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
136b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 2:
137b3c9d1c33caf325aada244204215eb790c228c12dandov                        paint.setShader(shader);
138b3c9d1c33caf325aada244204215eb790c228c12dandov                        canvas->drawPatch(cubics, NULL, texCoords, xfer, paint);
139b3c9d1c33caf325aada244204215eb790c228c12dandov                        paint.setShader(NULL);
140b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
141b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 3:
142b3c9d1c33caf325aada244204215eb790c228c12dandov                        paint.setShader(shader);
143b3c9d1c33caf325aada244204215eb790c228c12dandov                        canvas->drawPatch(cubics, colors, texCoords, xfer, paint);
144b3c9d1c33caf325aada244204215eb790c228c12dandov                        paint.setShader(NULL);
145b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
146b3c9d1c33caf325aada244204215eb790c228c12dandov                    default:
147b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
148b3c9d1c33caf325aada244204215eb790c228c12dandov                }
149b3c9d1c33caf325aada244204215eb790c228c12dandov
150b3c9d1c33caf325aada244204215eb790c228c12dandov                draw_control_points(canvas, cubics);
151b3c9d1c33caf325aada244204215eb790c228c12dandov                canvas->restore();
152b3c9d1c33caf325aada244204215eb790c228c12dandov            }
153ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov        }
154ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov        canvas->restore();
15550d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    }
15650d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
15750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandovprivate:
15850d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov    typedef GM INHERITED;
15950d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov};
16050d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
161ecfff21bde1f0ca3c36533eded325066b5f2d42ddandovDEF_GM(return SkNEW(SkPatchGM); )
16250d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
16350d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov}
164