• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 #include "gm.h"
10 #include "SkCanvas.h"
11 #include "SkAAClip.h"
12 
13 namespace skiagm {
14 
paint_rgn(SkCanvas * canvas,const SkAAClip & clip,const SkPaint & paint)15 static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip,
16                       const SkPaint& paint) {
17     SkMask mask;
18     SkBitmap bm;
19 
20     clip.copyToMask(&mask);
21 
22     SkAutoMaskFreeImage amfi(mask.fImage);
23 
24     bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
25                  mask.fBounds.height(), mask.fRowBytes);
26     bm.setPixels(mask.fImage);
27 
28     // need to copy for deferred drawing test to work
29     SkBitmap bm2;
30 
31     bm.deepCopyTo(&bm2, SkBitmap::kA8_Config);
32 
33     canvas->drawBitmap(bm2,
34                        SK_Scalar1 * mask.fBounds.fLeft,
35                        SK_Scalar1 * mask.fBounds.fTop,
36                        &paint);
37 }
38 
39 //////////////////////////////////////////////////////////////////////////////
40 /*
41  * This GM tests anti aliased single operation booleans with SkAAClips,
42  * SkRect and SkPaths.
43  */
44 class SimpleClipGM : public GM {
45 public:
46     enum SkGeomTypes {
47         kRect_GeomType,
48         kPath_GeomType,
49         kAAClip_GeomType
50     };
51 
SimpleClipGM(SkGeomTypes geomType)52     SimpleClipGM(SkGeomTypes geomType)
53     : fGeomType(geomType) {
54 
55         // offset the rects a bit so we get anti-aliasing in the rect case
56         fBase.set(SkFloatToScalar(100.65f),
57                   SkFloatToScalar(100.65f),
58                   SkFloatToScalar(150.65f),
59                   SkFloatToScalar(150.65f));
60         fRect = fBase;
61         fRect.inset(5, 5);
62         fRect.offset(25, 25);
63 
64         fBasePath.addRoundRect(fBase, SkIntToScalar(5), SkIntToScalar(5));
65         fRectPath.addRoundRect(fRect, SkIntToScalar(5), SkIntToScalar(5));
66         INHERITED::setBGColor(0xFFDDDDDD);
67     }
68 
69 protected:
buildRgn(SkAAClip * clip,SkRegion::Op op)70     void buildRgn(SkAAClip* clip, SkRegion::Op op) {
71         clip->setPath(fBasePath, NULL, true);
72 
73         SkAAClip clip2;
74         clip2.setPath(fRectPath, NULL, true);
75         clip->op(clip2, op);
76     }
77 
drawOrig(SkCanvas * canvas)78     void drawOrig(SkCanvas* canvas) {
79         SkPaint     paint;
80 
81         paint.setStyle(SkPaint::kStroke_Style);
82         paint.setColor(SK_ColorBLACK);
83 
84         canvas->drawRect(fBase, paint);
85         canvas->drawRect(fRect, paint);
86     }
87 
drawRgnOped(SkCanvas * canvas,SkRegion::Op op,SkColor color)88     void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
89 
90         SkAAClip clip;
91 
92         this->buildRgn(&clip, op);
93         this->drawOrig(canvas);
94 
95         SkPaint paint;
96         paint.setColor(color);
97         paint_rgn(canvas, clip, paint);
98     }
99 
drawPathsOped(SkCanvas * canvas,SkRegion::Op op,SkColor color)100     void drawPathsOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
101 
102         this->drawOrig(canvas);
103 
104         canvas->save();
105 
106         // create the clip mask with the supplied boolean op
107         if (kPath_GeomType == fGeomType) {
108             // path-based case
109             canvas->clipPath(fBasePath, SkRegion::kReplace_Op, true);
110             canvas->clipPath(fRectPath, op, true);
111         } else {
112             // rect-based case
113             canvas->clipRect(fBase, SkRegion::kReplace_Op, true);
114             canvas->clipRect(fRect, op, true);
115         }
116 
117         // draw a rect that will entirely cover the clip mask area
118         SkPaint paint;
119         paint.setColor(color);
120 
121         SkRect r = SkRect::MakeLTRB(SkIntToScalar(90),  SkIntToScalar(90),
122                                     SkIntToScalar(180), SkIntToScalar(180));
123 
124         canvas->drawRect(r, paint);
125 
126         canvas->restore();
127     }
128 
onShortName()129     virtual SkString onShortName() {
130         SkString str;
131         str.printf("simpleaaclip_%s",
132                     kRect_GeomType == fGeomType ? "rect" :
133                     (kPath_GeomType == fGeomType ? "path" :
134                     "aaclip"));
135         return str;
136     }
137 
onISize()138     virtual SkISize onISize() {
139         return make_isize(640, 480);
140     }
141 
onDraw(SkCanvas * canvas)142     virtual void onDraw(SkCanvas* canvas) {
143 
144         static const struct {
145             SkColor         fColor;
146             const char*     fName;
147             SkRegion::Op    fOp;
148         } gOps[] = {
149             { SK_ColorBLACK,    "Difference", SkRegion::kDifference_Op    },
150             { SK_ColorRED,      "Intersect",  SkRegion::kIntersect_Op     },
151             { 0xFF008800,       "Union",      SkRegion::kUnion_Op         },
152             { SK_ColorGREEN,    "Rev Diff",   SkRegion::kReverseDifference_Op },
153             { SK_ColorYELLOW,   "Replace",    SkRegion::kReplace_Op       },
154             { SK_ColorBLUE,     "XOR",        SkRegion::kXOR_Op           },
155         };
156 
157         SkPaint textPaint;
158         textPaint.setAntiAlias(true);
159         textPaint.setTextSize(SK_Scalar1*24);
160         int xOff = 0;
161 
162         for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
163             canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
164                              SkIntToScalar(75), SkIntToScalar(50),
165                              textPaint);
166 
167             if (kAAClip_GeomType == fGeomType) {
168                 this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
169             } else {
170                 this->drawPathsOped(canvas, gOps[op].fOp, gOps[op].fColor);
171             }
172 
173             if (xOff >= 400) {
174                 canvas->translate(SkIntToScalar(-400), SkIntToScalar(250));
175                 xOff = 0;
176             } else {
177                 canvas->translate(SkIntToScalar(200), 0);
178                 xOff += 200;
179             }
180         }
181     }
182 private:
183 
184     SkGeomTypes fGeomType;
185 
186     SkRect fBase;
187     SkRect fRect;
188 
189     SkPath fBasePath;       // fBase as a round rect
190     SkPath fRectPath;       // fRect as a round rect
191 
192     typedef GM INHERITED;
193 };
194 
195 //////////////////////////////////////////////////////////////////////////////
196 
197 // rects
198 DEF_GM( return new SimpleClipGM(SimpleClipGM::kRect_GeomType); )
199 DEF_GM( return new SimpleClipGM(SimpleClipGM::kPath_GeomType); )
200 DEF_GM( return new SimpleClipGM(SimpleClipGM::kAAClip_GeomType); )
201 
202 }
203