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