150d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov/*
250d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov * Copyright 2014 Google Inc.
350d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov *
450d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov * Use of this source code is governed by a BSD-style license that can be
550d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov * found in the LICENSE file.
650d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov */
750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
850d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov#include "gm.h"
9b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkGradientShader.h"
10b3c9d1c33caf325aada244204215eb790c228c12dandov#include "SkPatchUtils.h"
11b3c9d1c33caf325aada244204215eb790c228c12dandov
121a9b9640843a64af8d9d90337ec3b3fea663196areedstatic sk_sp<SkShader> make_shader() {
13b3c9d1c33caf325aada244204215eb790c228c12dandov    const SkColor colors[] = {
14b3c9d1c33caf325aada244204215eb790c228c12dandov        SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, SK_ColorMAGENTA, SK_ColorBLUE,
15b3c9d1c33caf325aada244204215eb790c228c12dandov        SK_ColorYELLOW,
16b3c9d1c33caf325aada244204215eb790c228c12dandov    };
17b3c9d1c33caf325aada244204215eb790c228c12dandov    const SkPoint pts[] = { { 100.f / 4.f, 0.f }, { 3.f * 100.f / 4.f, 100.f } };
189d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
191a9b9640843a64af8d9d90337ec3b3fea663196areed    return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
201a9b9640843a64af8d9d90337ec3b3fea663196areed                                        SkShader::kMirror_TileMode);
21b3c9d1c33caf325aada244204215eb790c228c12dandov}
2250d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov
23b3c9d1c33caf325aada244204215eb790c228c12dandovstatic void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
24ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov    //draw control points
25963137b75c0a1fe91f35e9826742f36309f5e65ddandov    SkPaint paint;
26b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint bottom[SkPatchUtils::kNumPtsCubic];
27b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getBottomCubic(cubics, bottom);
28b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint top[SkPatchUtils::kNumPtsCubic];
29b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getTopCubic(cubics, top);
30b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint left[SkPatchUtils::kNumPtsCubic];
31b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getLeftCubic(cubics, left);
32b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPoint right[SkPatchUtils::kNumPtsCubic];
33b3c9d1c33caf325aada244204215eb790c228c12dandov    SkPatchUtils::getRightCubic(cubics, right);
34ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
35963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorBLACK);
36b3c9d1c33caf325aada244204215eb790c228c12dandov    paint.setStrokeWidth(0.5f);
37ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov    SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
38963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
39b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
40963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
41963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
42963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
43ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
44b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
45b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
46b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
47ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
48963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setStrokeWidth(2);
49ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
50963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorRED);
51963137b75c0a1fe91f35e9826742f36309f5e65ddandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
52ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
53963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorBLUE);
54b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
55ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
56963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorCYAN);
57b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
58ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
59963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorYELLOW);
60b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
61ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
62963137b75c0a1fe91f35e9826742f36309f5e65ddandov    paint.setColor(SK_ColorGREEN);
63b3c9d1c33caf325aada244204215eb790c228c12dandov    canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
64ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov}
65ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov
6611064dfeb49daa64bd4e539284b9a6d1b78d6e5emtkleinDEF_SIMPLE_GM(patch_primitive, canvas, 1500, 1100) {
6750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov        SkPaint paint;
689d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
69963137b75c0a1fe91f35e9826742f36309f5e65ddandov        // The order of the colors and points is clockwise starting at upper-left corner.
70b3c9d1c33caf325aada244204215eb790c228c12dandov        const SkPoint cubics[SkPatchUtils::kNumCtrlPts] = {
71963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //top points
72b3c9d1c33caf325aada244204215eb790c228c12dandov            {100,100},{150,50},{250,150}, {300,100},
73963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //right points
74b3c9d1c33caf325aada244204215eb790c228c12dandov            {250, 150},{350,250},
75963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //bottom points
76b3c9d1c33caf325aada244204215eb790c228c12dandov            {300,300},{250,250},{150,350},{100,300},
77963137b75c0a1fe91f35e9826742f36309f5e65ddandov            //left points
78b3c9d1c33caf325aada244204215eb790c228c12dandov            {50,250},{150,150}
7950d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov        };
809d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
81b3c9d1c33caf325aada244204215eb790c228c12dandov        const SkColor colors[SkPatchUtils::kNumCorners] = {
82b3c9d1c33caf325aada244204215eb790c228c12dandov            SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
83b3c9d1c33caf325aada244204215eb790c228c12dandov        };
84b3c9d1c33caf325aada244204215eb790c228c12dandov        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
85b3c9d1c33caf325aada244204215eb790c228c12dandov            {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}}
86b3c9d1c33caf325aada244204215eb790c228c12dandov        ;
879d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
887d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed        const SkBlendMode modes[] = {
897d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed            SkBlendMode::kSrc,
907d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed            SkBlendMode::kDst,
917d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed            SkBlendMode::kModulate,
92b3c9d1c33caf325aada244204215eb790c228c12dandov        };
939d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
941a9b9640843a64af8d9d90337ec3b3fea663196areed        sk_sp<SkShader> shader(make_shader());
959d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
96b3c9d1c33caf325aada244204215eb790c228c12dandov        canvas->save();
97b3c9d1c33caf325aada244204215eb790c228c12dandov        for (int y = 0; y < 3; y++) {
98b3c9d1c33caf325aada244204215eb790c228c12dandov            for (int x = 0; x < 4; x++) {
99b3c9d1c33caf325aada244204215eb790c228c12dandov                canvas->save();
100b3c9d1c33caf325aada244204215eb790c228c12dandov                canvas->translate(x * 350.0f, y * 350.0f);
101b3c9d1c33caf325aada244204215eb790c228c12dandov                switch (x) {
102b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 0:
1037d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                        canvas->drawPatch(cubics, nullptr, nullptr, modes[y], paint);
104b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
105b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 1:
1067d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                        canvas->drawPatch(cubics, colors, nullptr, modes[y], paint);
107b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
108b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 2:
109b3c9d1c33caf325aada244204215eb790c228c12dandov                        paint.setShader(shader);
1107d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                        canvas->drawPatch(cubics, nullptr, texCoords, modes[y], paint);
11196fcdcc219d2a0d3579719b84b28bede76efba64halcanary                        paint.setShader(nullptr);
112b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
113b3c9d1c33caf325aada244204215eb790c228c12dandov                    case 3:
114b3c9d1c33caf325aada244204215eb790c228c12dandov                        paint.setShader(shader);
1157d954ad797176afedb9262fdea4507d0fc60eb9dMike Reed                        canvas->drawPatch(cubics, colors, texCoords, modes[y], paint);
11696fcdcc219d2a0d3579719b84b28bede76efba64halcanary                        paint.setShader(nullptr);
117b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
118b3c9d1c33caf325aada244204215eb790c228c12dandov                    default:
119b3c9d1c33caf325aada244204215eb790c228c12dandov                        break;
120b3c9d1c33caf325aada244204215eb790c228c12dandov                }
1219d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
122b3c9d1c33caf325aada244204215eb790c228c12dandov                draw_control_points(canvas, cubics);
123b3c9d1c33caf325aada244204215eb790c228c12dandov                canvas->restore();
124b3c9d1c33caf325aada244204215eb790c228c12dandov            }
125ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov        }
126ecfff21bde1f0ca3c36533eded325066b5f2d42ddandov        canvas->restore();
12750d715476b1d3a00fb43c13e34a80ea0a01d32bfdandov}
128