1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "gm/gm.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBlendMode.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColor.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathBuilder.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSize.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkCanvasPriv.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
22*c8dee2aaSAndroid Build Coastguard Worker
23*c8dee2aaSAndroid Build Coastguard Worker /** Draw a 2px border around the target, then red behind the target;
24*c8dee2aaSAndroid Build Coastguard Worker set the clip to match the target, then draw >> the target in blue.
25*c8dee2aaSAndroid Build Coastguard Worker */
26*c8dee2aaSAndroid Build Coastguard Worker
draw(SkCanvas * canvas,SkRect & target,int x,int y)27*c8dee2aaSAndroid Build Coastguard Worker static void draw(SkCanvas* canvas, SkRect& target, int x, int y) {
28*c8dee2aaSAndroid Build Coastguard Worker SkPaint borderPaint;
29*c8dee2aaSAndroid Build Coastguard Worker borderPaint.setColor(SkColorSetRGB(0x0, 0xDD, 0x0));
30*c8dee2aaSAndroid Build Coastguard Worker borderPaint.setAntiAlias(true);
31*c8dee2aaSAndroid Build Coastguard Worker SkPaint backgroundPaint;
32*c8dee2aaSAndroid Build Coastguard Worker backgroundPaint.setColor(SkColorSetRGB(0xDD, 0x0, 0x0));
33*c8dee2aaSAndroid Build Coastguard Worker backgroundPaint.setAntiAlias(true);
34*c8dee2aaSAndroid Build Coastguard Worker SkPaint foregroundPaint;
35*c8dee2aaSAndroid Build Coastguard Worker foregroundPaint.setColor(SkColorSetRGB(0x0, 0x0, 0xDD));
36*c8dee2aaSAndroid Build Coastguard Worker foregroundPaint.setAntiAlias(true);
37*c8dee2aaSAndroid Build Coastguard Worker
38*c8dee2aaSAndroid Build Coastguard Worker canvas->save();
39*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
40*c8dee2aaSAndroid Build Coastguard Worker target.inset(SkIntToScalar(-2), SkIntToScalar(-2));
41*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(target, borderPaint);
42*c8dee2aaSAndroid Build Coastguard Worker target.inset(SkIntToScalar(2), SkIntToScalar(2));
43*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(target, backgroundPaint);
44*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(target, true);
45*c8dee2aaSAndroid Build Coastguard Worker target.inset(SkIntToScalar(-4), SkIntToScalar(-4));
46*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(target, foregroundPaint);
47*c8dee2aaSAndroid Build Coastguard Worker canvas->restore();
48*c8dee2aaSAndroid Build Coastguard Worker }
49*c8dee2aaSAndroid Build Coastguard Worker
draw_square(SkCanvas * canvas,int x,int y)50*c8dee2aaSAndroid Build Coastguard Worker static void draw_square(SkCanvas* canvas, int x, int y) {
51*c8dee2aaSAndroid Build Coastguard Worker SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 10 * SK_Scalar1));
52*c8dee2aaSAndroid Build Coastguard Worker draw(canvas, target, x, y);
53*c8dee2aaSAndroid Build Coastguard Worker }
54*c8dee2aaSAndroid Build Coastguard Worker
draw_column(SkCanvas * canvas,int x,int y)55*c8dee2aaSAndroid Build Coastguard Worker static void draw_column(SkCanvas* canvas, int x, int y) {
56*c8dee2aaSAndroid Build Coastguard Worker SkRect target (SkRect::MakeWH(1 * SK_Scalar1, 10 * SK_Scalar1));
57*c8dee2aaSAndroid Build Coastguard Worker draw(canvas, target, x, y);
58*c8dee2aaSAndroid Build Coastguard Worker }
59*c8dee2aaSAndroid Build Coastguard Worker
draw_bar(SkCanvas * canvas,int x,int y)60*c8dee2aaSAndroid Build Coastguard Worker static void draw_bar(SkCanvas* canvas, int x, int y) {
61*c8dee2aaSAndroid Build Coastguard Worker SkRect target (SkRect::MakeWH(10 * SK_Scalar1, 1 * SK_Scalar1));
62*c8dee2aaSAndroid Build Coastguard Worker draw(canvas, target, x, y);
63*c8dee2aaSAndroid Build Coastguard Worker }
64*c8dee2aaSAndroid Build Coastguard Worker
draw_rect_tests(SkCanvas * canvas)65*c8dee2aaSAndroid Build Coastguard Worker static void draw_rect_tests(SkCanvas* canvas) {
66*c8dee2aaSAndroid Build Coastguard Worker draw_square(canvas, 10, 10);
67*c8dee2aaSAndroid Build Coastguard Worker draw_column(canvas, 30, 10);
68*c8dee2aaSAndroid Build Coastguard Worker draw_bar(canvas, 10, 30);
69*c8dee2aaSAndroid Build Coastguard Worker }
70*c8dee2aaSAndroid Build Coastguard Worker
71*c8dee2aaSAndroid Build Coastguard Worker /**
72*c8dee2aaSAndroid Build Coastguard Worker Test a set of clipping problems discovered while writing blitAntiRect,
73*c8dee2aaSAndroid Build Coastguard Worker and test all the code paths through the clipping blitters.
74*c8dee2aaSAndroid Build Coastguard Worker Each region should show as a blue center surrounded by a 2px green
75*c8dee2aaSAndroid Build Coastguard Worker border, with no red.
76*c8dee2aaSAndroid Build Coastguard Worker */
77*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(aaclip, canvas, 240, 120) {
78*c8dee2aaSAndroid Build Coastguard Worker // Initial pixel-boundary-aligned draw
79*c8dee2aaSAndroid Build Coastguard Worker draw_rect_tests(canvas);
80*c8dee2aaSAndroid Build Coastguard Worker
81*c8dee2aaSAndroid Build Coastguard Worker // Repeat 4x with .2, .4, .6, .8 px offsets
82*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
83*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(50), 0);
84*c8dee2aaSAndroid Build Coastguard Worker draw_rect_tests(canvas);
85*c8dee2aaSAndroid Build Coastguard Worker
86*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
87*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(50), 0);
88*c8dee2aaSAndroid Build Coastguard Worker draw_rect_tests(canvas);
89*c8dee2aaSAndroid Build Coastguard Worker
90*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
91*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(50), 0);
92*c8dee2aaSAndroid Build Coastguard Worker draw_rect_tests(canvas);
93*c8dee2aaSAndroid Build Coastguard Worker
94*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SK_Scalar1 / 5, SK_Scalar1 / 5);
95*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(50), 0);
96*c8dee2aaSAndroid Build Coastguard Worker draw_rect_tests(canvas);
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker
99*c8dee2aaSAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////
100*c8dee2aaSAndroid Build Coastguard Worker
101*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_BUILD_FOR_MAC
102*c8dee2aaSAndroid Build Coastguard Worker
103*c8dee2aaSAndroid Build Coastguard Worker #include "include/utils/mac/SkCGUtils.h"
104*c8dee2aaSAndroid Build Coastguard Worker
make_canvas(const SkBitmap & bm)105*c8dee2aaSAndroid Build Coastguard Worker static std::unique_ptr<SkCanvas> make_canvas(const SkBitmap& bm) {
106*c8dee2aaSAndroid Build Coastguard Worker return SkCanvas::MakeRasterDirect(bm.info(), bm.getPixels(), bm.rowBytes());
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker
test_image(SkCanvas * canvas,const SkImageInfo & info)109*c8dee2aaSAndroid Build Coastguard Worker static void test_image(SkCanvas* canvas, const SkImageInfo& info) {
110*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bm;
111*c8dee2aaSAndroid Build Coastguard Worker bm.allocPixels(info);
112*c8dee2aaSAndroid Build Coastguard Worker
113*c8dee2aaSAndroid Build Coastguard Worker if (info.isOpaque()) {
114*c8dee2aaSAndroid Build Coastguard Worker bm.eraseColor(SK_ColorGREEN);
115*c8dee2aaSAndroid Build Coastguard Worker } else {
116*c8dee2aaSAndroid Build Coastguard Worker bm.eraseColor(0);
117*c8dee2aaSAndroid Build Coastguard Worker }
118*c8dee2aaSAndroid Build Coastguard Worker
119*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
120*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
121*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLUE);
122*c8dee2aaSAndroid Build Coastguard Worker make_canvas(bm)->drawCircle(50, 50, 49, paint);
123*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImage(bm.asImage(), 10, 10);
124*c8dee2aaSAndroid Build Coastguard Worker
125*c8dee2aaSAndroid Build Coastguard Worker CGImageRef image = SkCreateCGImageRefWithColorspace(bm, nullptr);
126*c8dee2aaSAndroid Build Coastguard Worker
127*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bm2;
128*c8dee2aaSAndroid Build Coastguard Worker SkCreateBitmapFromCGImage(&bm2, image);
129*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImage(bm2.asImage(), 10, 120);
130*c8dee2aaSAndroid Build Coastguard Worker canvas->drawImage(SkMakeImageFromCGImage(image), 10, 120 + bm2.height() + 10);
131*c8dee2aaSAndroid Build Coastguard Worker
132*c8dee2aaSAndroid Build Coastguard Worker CGImageRelease(image);
133*c8dee2aaSAndroid Build Coastguard Worker }
134*c8dee2aaSAndroid Build Coastguard Worker
135*c8dee2aaSAndroid Build Coastguard Worker DEF_SIMPLE_GM(cgimage, canvas, 800, 250) {
136*c8dee2aaSAndroid Build Coastguard Worker const struct {
137*c8dee2aaSAndroid Build Coastguard Worker SkColorType fCT;
138*c8dee2aaSAndroid Build Coastguard Worker SkAlphaType fAT;
139*c8dee2aaSAndroid Build Coastguard Worker } rec[] = {
140*c8dee2aaSAndroid Build Coastguard Worker { kRGB_565_SkColorType, kOpaque_SkAlphaType },
141*c8dee2aaSAndroid Build Coastguard Worker
142*c8dee2aaSAndroid Build Coastguard Worker { kRGBA_8888_SkColorType, kPremul_SkAlphaType },
143*c8dee2aaSAndroid Build Coastguard Worker { kRGBA_8888_SkColorType, kUnpremul_SkAlphaType },
144*c8dee2aaSAndroid Build Coastguard Worker { kRGBA_8888_SkColorType, kOpaque_SkAlphaType },
145*c8dee2aaSAndroid Build Coastguard Worker
146*c8dee2aaSAndroid Build Coastguard Worker { kBGRA_8888_SkColorType, kPremul_SkAlphaType },
147*c8dee2aaSAndroid Build Coastguard Worker { kBGRA_8888_SkColorType, kUnpremul_SkAlphaType },
148*c8dee2aaSAndroid Build Coastguard Worker { kBGRA_8888_SkColorType, kOpaque_SkAlphaType },
149*c8dee2aaSAndroid Build Coastguard Worker };
150*c8dee2aaSAndroid Build Coastguard Worker
151*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(rec); ++i) {
152*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo info = SkImageInfo::Make(100, 100, rec[i].fCT, rec[i].fAT);
153*c8dee2aaSAndroid Build Coastguard Worker test_image(canvas, info);
154*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(info.width() + 10, 0);
155*c8dee2aaSAndroid Build Coastguard Worker }
156*c8dee2aaSAndroid Build Coastguard Worker }
157*c8dee2aaSAndroid Build Coastguard Worker
158*c8dee2aaSAndroid Build Coastguard Worker #endif
159*c8dee2aaSAndroid Build Coastguard Worker
160*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////////////////////////
161*c8dee2aaSAndroid Build Coastguard Worker
162*c8dee2aaSAndroid Build Coastguard Worker // https://bug.skia.org/3716
163*c8dee2aaSAndroid Build Coastguard Worker class ClipCubicGM : public skiagm::GM {
164*c8dee2aaSAndroid Build Coastguard Worker const SkScalar W = 100;
165*c8dee2aaSAndroid Build Coastguard Worker const SkScalar H = 240;
166*c8dee2aaSAndroid Build Coastguard Worker
167*c8dee2aaSAndroid Build Coastguard Worker SkPath fVPath, fHPath;
168*c8dee2aaSAndroid Build Coastguard Worker public:
ClipCubicGM()169*c8dee2aaSAndroid Build Coastguard Worker ClipCubicGM() {
170*c8dee2aaSAndroid Build Coastguard Worker fVPath = SkPathBuilder().moveTo(W, 0)
171*c8dee2aaSAndroid Build Coastguard Worker .cubicTo(W, H-10, 0, 10, 0, H)
172*c8dee2aaSAndroid Build Coastguard Worker .detach();
173*c8dee2aaSAndroid Build Coastguard Worker
174*c8dee2aaSAndroid Build Coastguard Worker SkMatrix pivot;
175*c8dee2aaSAndroid Build Coastguard Worker pivot.setRotate(90, W/2, H/2);
176*c8dee2aaSAndroid Build Coastguard Worker fHPath = fVPath.makeTransform(pivot);
177*c8dee2aaSAndroid Build Coastguard Worker }
178*c8dee2aaSAndroid Build Coastguard Worker
179*c8dee2aaSAndroid Build Coastguard Worker protected:
getName() const180*c8dee2aaSAndroid Build Coastguard Worker SkString getName() const override { return SkString("clipcubic"); }
181*c8dee2aaSAndroid Build Coastguard Worker
getISize()182*c8dee2aaSAndroid Build Coastguard Worker SkISize getISize() override { return SkISize::Make(400, 410); }
183*c8dee2aaSAndroid Build Coastguard Worker
doDraw(SkCanvas * canvas,const SkPath & path)184*c8dee2aaSAndroid Build Coastguard Worker void doDraw(SkCanvas* canvas, const SkPath& path) {
185*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
186*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
187*c8dee2aaSAndroid Build Coastguard Worker
188*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(0xFFCCCCCC);
189*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint);
190*c8dee2aaSAndroid Build Coastguard Worker
191*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorRED);
192*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
193*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint);
194*c8dee2aaSAndroid Build Coastguard Worker }
195*c8dee2aaSAndroid Build Coastguard Worker
drawAndClip(SkCanvas * canvas,const SkPath & path,SkScalar dx,SkScalar dy)196*c8dee2aaSAndroid Build Coastguard Worker void drawAndClip(SkCanvas* canvas, const SkPath& path, SkScalar dx, SkScalar dy) {
197*c8dee2aaSAndroid Build Coastguard Worker SkAutoCanvasRestore acr(canvas, true);
198*c8dee2aaSAndroid Build Coastguard Worker
199*c8dee2aaSAndroid Build Coastguard Worker SkRect r = SkRect::MakeXYWH(0, H/4, W, H/2);
200*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
201*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(ToolUtils::color_to_565(0xFF8888FF));
202*c8dee2aaSAndroid Build Coastguard Worker
203*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(r, paint);
204*c8dee2aaSAndroid Build Coastguard Worker this->doDraw(canvas, path);
205*c8dee2aaSAndroid Build Coastguard Worker
206*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(dx, dy);
207*c8dee2aaSAndroid Build Coastguard Worker
208*c8dee2aaSAndroid Build Coastguard Worker canvas->drawRect(r, paint);
209*c8dee2aaSAndroid Build Coastguard Worker canvas->clipRect(r);
210*c8dee2aaSAndroid Build Coastguard Worker this->doDraw(canvas, path);
211*c8dee2aaSAndroid Build Coastguard Worker }
212*c8dee2aaSAndroid Build Coastguard Worker
onDraw(SkCanvas * canvas)213*c8dee2aaSAndroid Build Coastguard Worker void onDraw(SkCanvas* canvas) override {
214*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(80, 10);
215*c8dee2aaSAndroid Build Coastguard Worker this->drawAndClip(canvas, fVPath, 200, 0);
216*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, 200);
217*c8dee2aaSAndroid Build Coastguard Worker this->drawAndClip(canvas, fHPath, 200, 0);
218*c8dee2aaSAndroid Build Coastguard Worker }
219*c8dee2aaSAndroid Build Coastguard Worker
220*c8dee2aaSAndroid Build Coastguard Worker private:
221*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = skiagm::GM;
222*c8dee2aaSAndroid Build Coastguard Worker };
223*c8dee2aaSAndroid Build Coastguard Worker DEF_GM(return new ClipCubicGM;)
224