1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "SkAAClip.h" 9 #include "SampleCode.h" 10 #include "SkView.h" 11 #include "SkCanvas.h" 12 #include "SkGradientShader.h" 13 #include "SkPath.h" 14 #include "SkRegion.h" 15 #include "SkShader.h" 16 #include "SkUtils.h" 17 #include "SkImageDecoder.h" 18 19 #ifdef SK_BUILD_FOR_WIN 20 // windows doesn't have roundf 21 inline float roundf(float x) { return (x-floor(x))>0.5 ? ceil(x) : floor(x); } 22 #endif 23 24 static void drawClip(SkCanvas* canvas, const SkAAClip& clip) { 25 SkMask mask; 26 SkBitmap bm; 27 28 clip.copyToMask(&mask); 29 SkAutoMaskFreeImage amfi(mask.fImage); 30 31 bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(), 32 mask.fBounds.height(), mask.fRowBytes); 33 bm.setPixels(mask.fImage); 34 35 SkPaint paint; 36 canvas->drawBitmap(bm, 37 SK_Scalar1 * mask.fBounds.fLeft, 38 SK_Scalar1 * mask.fBounds.fTop, 39 &paint); 40 } 41 42 static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip, 43 const SkPaint& paint) { 44 SkMask mask; 45 SkBitmap bm; 46 47 clip.copyToMask(&mask); 48 SkAutoMaskFreeImage amfi(mask.fImage); 49 50 bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(), 51 mask.fBounds.height(), mask.fRowBytes); 52 bm.setPixels(mask.fImage); 53 54 canvas->drawBitmap(bm, 55 SK_Scalar1 * mask.fBounds.fLeft, 56 SK_Scalar1 * mask.fBounds.fTop, 57 &paint); 58 } 59 60 class AAClipView2 : public SampleView { 61 public: 62 AAClipView2() { 63 fBase.set(100, 100, 150, 150); 64 fRect = fBase; 65 fRect.inset(5, 5); 66 fRect.offset(25, 25); 67 this->setBGColor(0xFFDDDDDD); 68 } 69 70 static void setAAClip(SkAAClip* clip, const SkIRect& rect) { 71 SkRect r; 72 r.set(rect); 73 SkPath path; 74 path.addRoundRect(r, SkIntToScalar(5), SkIntToScalar(5)); 75 clip->setPath(path); 76 } 77 78 void build_rgn(SkAAClip* clip, SkRegion::Op op) { 79 setAAClip(clip, fBase); 80 81 SkAAClip clip2; 82 setAAClip(&clip2, fRect); 83 clip->op(clip2, op); 84 } 85 86 87 protected: 88 // overrides from SkEventSink 89 virtual bool onQuery(SkEvent* evt) { 90 if (SampleCode::TitleQ(*evt)) { 91 SampleCode::TitleR(evt, "AAClips"); 92 return true; 93 } 94 return this->INHERITED::onQuery(evt); 95 } 96 97 void drawOrig(SkCanvas* canvas, bool bg) { 98 SkRect r; 99 SkPaint paint; 100 101 paint.setStyle(SkPaint::kStroke_Style); 102 if (bg) 103 paint.setColor(0xFFBBBBBB); 104 105 r.set(fBase); 106 canvas->drawRect(r, paint); 107 r.set(fRect); 108 canvas->drawRect(r, paint); 109 } 110 111 static void outer_frame(SkCanvas* canvas, const SkIRect& rect) { 112 SkRect r; 113 r.set(rect); 114 r.inset(-SK_ScalarHalf, -SK_ScalarHalf); 115 116 SkPaint paint; 117 paint.setColor(SK_ColorGRAY); 118 paint.setStyle(SkPaint::kStroke_Style); 119 canvas->drawRect(r, paint); 120 } 121 122 void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) { 123 SkAAClip clip; 124 125 this->build_rgn(&clip, op); 126 127 this->drawOrig(canvas, true); 128 129 SkPaint paint; 130 paint.setColor((color & ~(0xFF << 24)) | (0x44 << 24)); 131 paint_rgn(canvas, clip, paint); 132 133 paint.setStyle(SkPaint::kStroke_Style); 134 paint.setColor(color); 135 paint_rgn(canvas, clip, paint); 136 137 SkAAClip clip2(clip); 138 clip2.translate(0, 80); 139 outer_frame(canvas, clip2.getBounds()); 140 paint_rgn(canvas, clip2, paint); 141 } 142 143 virtual void onDrawContent(SkCanvas* canvas) { 144 145 static const struct { 146 SkColor fColor; 147 const char* fName; 148 SkRegion::Op fOp; 149 } gOps[] = { 150 { SK_ColorBLACK, "Difference", SkRegion::kDifference_Op }, 151 { SK_ColorRED, "Intersect", SkRegion::kIntersect_Op }, 152 { 0xFF008800, "Union", SkRegion::kUnion_Op }, 153 { SK_ColorBLUE, "XOR", SkRegion::kXOR_Op } 154 }; 155 156 SkPaint textPaint; 157 textPaint.setAntiAlias(true); 158 textPaint.setTextSize(SK_Scalar1*24); 159 160 this->drawOrig(canvas, false); 161 162 canvas->translate(0, SkIntToScalar(200)); 163 164 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) { 165 canvas->drawText(gOps[op].fName, strlen(gOps[op].fName), SkIntToScalar(75), SkIntToScalar(50), textPaint); 166 167 this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor); 168 169 canvas->translate(SkIntToScalar(200), 0); 170 } 171 } 172 173 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) { 174 return fRect.contains(SkScalarRound(x), SkScalarRound(y)) ? new Click(this) : NULL; 175 } 176 177 virtual bool onClick(Click* click) { 178 fRect.offset(click->fICurr.fX - click->fIPrev.fX, 179 click->fICurr.fY - click->fIPrev.fY); 180 this->inval(NULL); 181 return true; 182 } 183 184 private: 185 SkIRect fBase, fRect; 186 187 typedef SampleView INHERITED; 188 }; 189 190 ////////////////////////////////////////////////////////////////////////////// 191 192 static SkView* MyFactory() { return new AAClipView2; } 193 static SkViewRegister reg(MyFactory); 194 195