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