• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "gm.h"
9 #include "SkGradientShader.h"
10 #include "SkImage.h"
11 #include "SkPatchUtils.h"
12 #include "SkPath.h"
13 
make_shader()14 static sk_sp<SkShader> make_shader() {
15     const SkColor colors[] = {
16         SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, SK_ColorMAGENTA, SK_ColorBLUE,
17         SK_ColorYELLOW,
18     };
19     const SkPoint pts[] = { { 100.f / 4.f, 0.f }, { 3.f * 100.f / 4.f, 100.f } };
20 
21     return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
22                                         SkShader::kMirror_TileMode);
23 }
24 
draw_control_points(SkCanvas * canvas,const SkPoint cubics[12])25 static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) {
26     //draw control points
27     SkPaint paint;
28     SkPoint bottom[SkPatchUtils::kNumPtsCubic];
29     SkPatchUtils::GetBottomCubic(cubics, bottom);
30     SkPoint top[SkPatchUtils::kNumPtsCubic];
31     SkPatchUtils::GetTopCubic(cubics, top);
32     SkPoint left[SkPatchUtils::kNumPtsCubic];
33     SkPatchUtils::GetLeftCubic(cubics, left);
34     SkPoint right[SkPatchUtils::kNumPtsCubic];
35     SkPatchUtils::GetRightCubic(cubics, right);
36 
37     paint.setColor(SK_ColorBLACK);
38     paint.setStrokeWidth(0.5f);
39     SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] };
40     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint);
41     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom + 1, paint);
42     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint);
43     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint);
44     canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint);
45 
46     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top + 1, paint);
47     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left + 1, paint);
48     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right + 1, paint);
49 
50     paint.setStrokeWidth(2);
51 
52     paint.setColor(SK_ColorRED);
53     canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint);
54 
55     paint.setColor(SK_ColorBLUE);
56     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom + 1, paint);
57 
58     paint.setColor(SK_ColorCYAN);
59     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top + 1, paint);
60 
61     paint.setColor(SK_ColorYELLOW);
62     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left + 1, paint);
63 
64     paint.setColor(SK_ColorGREEN);
65     canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right + 1, paint);
66 }
67 
68 // The order of the colors and points is clockwise starting at upper-left corner.
69 const SkPoint gCubics[SkPatchUtils::kNumCtrlPts] = {
70     //top points
71     {100,100},{150,50},{250,150}, {300,100},
72     //right points
73     {250, 150},{350,250},
74     //bottom points
75     {300,300},{250,250},{150,350},{100,300},
76     //left points
77     {50,250},{150,150}
78 };
79 
80 const SkPoint gTexCoords[SkPatchUtils::kNumCorners] = {
81     {0.0f, 0.0f}, {100.0f, 0.0f}, {100.0f,100.0f}, {0.0f, 100.0f}
82 };
83 
84 
dopatch(SkCanvas * canvas,const SkColor colors[],sk_sp<SkImage> img=nullptr)85 static void dopatch(SkCanvas* canvas, const SkColor colors[], sk_sp<SkImage> img = nullptr) {
86     SkPaint paint;
87 
88     const SkBlendMode modes[] = {
89         SkBlendMode::kSrc,
90         SkBlendMode::kDst,
91         SkBlendMode::kModulate,
92     };
93 
94     SkPoint texStorage[4];
95     const SkPoint* tex = gTexCoords;
96 
97     sk_sp<SkShader> shader;
98     if (img) {
99         SkScalar w = img->width();
100         SkScalar h = img->height();
101         shader = img->makeShader(SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
102         texStorage[0].set(0, 0);
103         texStorage[1].set(w, 0);
104         texStorage[2].set(w, h);
105         texStorage[3].set(0, h);
106         tex = texStorage;
107     } else {
108         shader = make_shader();
109     }
110 
111     canvas->save();
112     for (int y = 0; y < 3; y++) {
113         for (int x = 0; x < 4; x++) {
114             canvas->save();
115             canvas->translate(x * 350.0f, y * 350.0f);
116             switch (x) {
117                 case 0:
118                     canvas->drawPatch(gCubics, nullptr, nullptr, modes[y], paint);
119                     break;
120                 case 1:
121                     canvas->drawPatch(gCubics, colors, nullptr, modes[y], paint);
122                     break;
123                 case 2:
124                     paint.setShader(shader);
125                     canvas->drawPatch(gCubics, nullptr, tex, modes[y], paint);
126                     paint.setShader(nullptr);
127                     break;
128                 case 3:
129                     paint.setShader(shader);
130                     canvas->drawPatch(gCubics, colors, tex, modes[y], paint);
131                     paint.setShader(nullptr);
132                     break;
133                 default:
134                     break;
135             }
136 
137             draw_control_points(canvas, gCubics);
138             canvas->restore();
139         }
140     }
141     canvas->restore();
142 }
143 
144 DEF_SIMPLE_GM(patch_primitive, canvas, 1500, 1100) {
145     const SkColor colors[SkPatchUtils::kNumCorners] = {
146         SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
147     };
148     dopatch(canvas, colors);
149 }
150 #include "Resources.h"
151 DEF_SIMPLE_GM(patch_image, canvas, 1500, 1100) {
152     const SkColor colors[SkPatchUtils::kNumCorners] = {
153         SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
154     };
155     dopatch(canvas, colors, GetResourceAsImage("mandrill_128.png"));
156 }
157 DEF_SIMPLE_GM(patch_alpha, canvas, 1500, 1100) {
158     const SkColor colors[SkPatchUtils::kNumCorners] = {
159         SK_ColorRED, 0x0000FF00, SK_ColorBLUE, 0x00FF00FF,
160     };
161     dopatch(canvas, colors);
162 }
163 
164 // These two should look the same (one patch, one simple path)
165 DEF_SIMPLE_GM(patch_alpha_test, canvas, 550, 250) {
166     canvas->translate(-75, -75);
167 
168     const SkColor colors[SkPatchUtils::kNumCorners] = {
169         0x80FF0000, 0x80FF0000, 0x80FF0000, 0x80FF0000,
170     };
171     SkPaint paint;
172     canvas->drawPatch(gCubics, colors, nullptr, SkBlendMode::kModulate, paint);
173 
174     canvas->translate(300, 0);
175 
176     SkPath path;
177     path.moveTo(gCubics[0]);
178     path.cubicTo(gCubics[ 1], gCubics[ 2], gCubics[ 3]);
179     path.cubicTo(gCubics[ 4], gCubics[ 5], gCubics[ 6]);
180     path.cubicTo(gCubics[ 7], gCubics[ 8], gCubics[ 9]);
181     path.cubicTo(gCubics[10], gCubics[11], gCubics[ 0]);
182     paint.setColor(colors[0]);
183     canvas->drawPath(path, paint);
184 }
185 
186