xref: /aosp_15_r20/external/skia/gm/simpleaaclip.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2012 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/SkBitmap.h"
10 #include "include/core/SkCanvas.h"
11 #include "include/core/SkClipOp.h"
12 #include "include/core/SkColor.h"
13 #include "include/core/SkFont.h"
14 #include "include/core/SkPaint.h"
15 #include "include/core/SkPath.h"
16 #include "include/core/SkRect.h"
17 #include "include/core/SkRegion.h"
18 #include "include/core/SkScalar.h"
19 #include "include/core/SkSize.h"
20 #include "include/core/SkString.h"
21 #include "include/core/SkTypeface.h"
22 #include "include/core/SkTypes.h"
23 #include "src/core/SkAAClip.h"
24 #include "src/core/SkMask.h"
25 #include "tools/ToolUtils.h"
26 #include "tools/fonts/FontToolUtils.h"
27 
28 namespace skiagm {
29 
paint_rgn(SkCanvas * canvas,const SkAAClip & clip,const SkPaint & paint)30 static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip,
31                       const SkPaint& paint) {
32     SkMaskBuilder mask;
33     SkBitmap bm;
34 
35     clip.copyToMask(&mask);
36 
37     SkAutoMaskFreeImage amfi(mask.image());
38 
39     bm.installMaskPixels(mask);
40 
41     // need to copy for deferred drawing test to work
42     SkBitmap bm2;
43 
44     ToolUtils::copy_to(&bm2, bm.colorType(), bm);
45 
46     canvas->drawImage(bm2.asImage(),
47                       SK_Scalar1 * mask.fBounds.fLeft,
48                       SK_Scalar1 * mask.fBounds.fTop,
49                       SkSamplingOptions(),
50                       &paint);
51 }
52 
53 //////////////////////////////////////////////////////////////////////////////
54 /*
55  * This GM tests anti aliased single operation booleans with SkAAClips,
56  * SkRect and SkPaths.
57  */
58 class SimpleClipGM : public GM {
59 public:
60     enum SkGeomTypes {
61         kRect_GeomType,
62         kPath_GeomType,
63         kAAClip_GeomType
64     };
65 
SimpleClipGM(SkGeomTypes geomType)66     SimpleClipGM(SkGeomTypes geomType)
67     : fGeomType(geomType) {
68     }
69 
70 protected:
onOnceBeforeDraw()71     void onOnceBeforeDraw() override {
72         // offset the rects a bit so we get anti-aliasing in the rect case
73         fBase.setLTRB(100.65f,
74                       100.65f,
75                       150.65f,
76                       150.65f);
77         fRect = fBase;
78         fRect.inset(5, 5);
79         fRect.offset(25, 25);
80 
81         fBasePath.addRoundRect(fBase, SkIntToScalar(5), SkIntToScalar(5));
82         fRectPath.addRoundRect(fRect, SkIntToScalar(5), SkIntToScalar(5));
83         INHERITED::setBGColor(0xFFDDDDDD);
84     }
85 
buildRgn(SkAAClip * clip,SkClipOp op)86     void buildRgn(SkAAClip* clip, SkClipOp op) {
87         clip->setPath(fBasePath, fBasePath.getBounds().roundOut(), true);
88 
89         SkAAClip clip2;
90         clip2.setPath(fRectPath, fRectPath.getBounds().roundOut(), true);
91         clip->op(clip2, op);
92     }
93 
drawOrig(SkCanvas * canvas)94     void drawOrig(SkCanvas* canvas) {
95         SkPaint     paint;
96 
97         paint.setStyle(SkPaint::kStroke_Style);
98         paint.setColor(SK_ColorBLACK);
99 
100         canvas->drawRect(fBase, paint);
101         canvas->drawRect(fRect, paint);
102     }
103 
drawRgnOped(SkCanvas * canvas,SkClipOp op,SkColor color)104     void drawRgnOped(SkCanvas* canvas, SkClipOp op, SkColor color) {
105 
106         SkAAClip clip;
107 
108         this->buildRgn(&clip, op);
109         this->drawOrig(canvas);
110 
111         SkPaint paint;
112         paint.setColor(color);
113         paint_rgn(canvas, clip, paint);
114     }
115 
drawPathsOped(SkCanvas * canvas,SkClipOp op,SkColor color)116     void drawPathsOped(SkCanvas* canvas, SkClipOp op, SkColor color) {
117 
118         this->drawOrig(canvas);
119 
120         canvas->save();
121 
122         // create the clip mask with the supplied boolean op
123         if (kPath_GeomType == fGeomType) {
124             // path-based case
125             canvas->clipPath(fBasePath, true);
126             canvas->clipPath(fRectPath, op, true);
127         } else {
128             // rect-based case
129             canvas->clipRect(fBase, true);
130             canvas->clipRect(fRect, op, true);
131         }
132 
133         // draw a rect that will entirely cover the clip mask area
134         SkPaint paint;
135         paint.setColor(color);
136 
137         SkRect r = SkRect::MakeLTRB(SkIntToScalar(90),  SkIntToScalar(90),
138                                     SkIntToScalar(180), SkIntToScalar(180));
139 
140         canvas->drawRect(r, paint);
141 
142         canvas->restore();
143     }
144 
getName() const145     SkString getName() const override {
146         SkString str;
147         str.printf("simpleaaclip_%s",
148                     kRect_GeomType == fGeomType ? "rect" :
149                     (kPath_GeomType == fGeomType ? "path" :
150                     "aaclip"));
151         return str;
152     }
153 
getISize()154     SkISize getISize() override { return SkISize::Make(500, 240); }
155 
onDraw(SkCanvas * canvas)156     void onDraw(SkCanvas* canvas) override {
157 
158         const struct {
159             SkColor         fColor;
160             const char*     fName;
161             SkClipOp        fOp;
162         } gOps[] = {
163                 {SK_ColorBLACK, "Difference", SkClipOp::kDifference},
164                 {SK_ColorRED, "Intersect", SkClipOp::kIntersect},
165         };
166 
167         SkPaint textPaint;
168         SkFont  font(ToolUtils::DefaultPortableTypeface(), 24);
169         int xOff = 0;
170 
171         for (size_t op = 0; op < std::size(gOps); op++) {
172             canvas->drawString(gOps[op].fName, 75.0f, 50.0f, font, textPaint);
173 
174             if (kAAClip_GeomType == fGeomType) {
175                 this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
176             } else {
177                 this->drawPathsOped(canvas, gOps[op].fOp, gOps[op].fColor);
178             }
179 
180             if (xOff >= 400) {
181                 canvas->translate(SkIntToScalar(-400), SkIntToScalar(250));
182                 xOff = 0;
183             } else {
184                 canvas->translate(SkIntToScalar(200), 0);
185                 xOff += 200;
186             }
187         }
188     }
189 private:
190 
191     SkGeomTypes fGeomType;
192 
193     SkRect fBase;
194     SkRect fRect;
195 
196     SkPath fBasePath;       // fBase as a round rect
197     SkPath fRectPath;       // fRect as a round rect
198 
199     using INHERITED = GM;
200 };
201 
202 //////////////////////////////////////////////////////////////////////////////
203 
204 // rects
205 DEF_GM( return new SimpleClipGM(SimpleClipGM::kRect_GeomType); )
206 DEF_GM( return new SimpleClipGM(SimpleClipGM::kPath_GeomType); )
207 DEF_GM( return new SimpleClipGM(SimpleClipGM::kAAClip_GeomType); )
208 
209 }  // namespace skiagm
210