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