Converted AAClips SampleApp slide to GM:simpleaaclip
http://codereview.appspot.com/6220043/
git-svn-id: http://skia.googlecode.com/svn/trunk@4025 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/simpleaaclip.cpp b/gm/simpleaaclip.cpp
new file mode 100644
index 0000000..6873816
--- /dev/null
+++ b/gm/simpleaaclip.cpp
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2012 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+
+#include "gm.h"
+#include "SkCanvas.h"
+#include "SkAAClip.h"
+
+namespace skiagm {
+
+static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip,
+ const SkPaint& paint) {
+ SkMask mask;
+ SkBitmap bm;
+
+ clip.copyToMask(&mask);
+
+ SkAutoMaskFreeImage amfi(mask.fImage);
+
+ bm.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
+ mask.fBounds.height(), mask.fRowBytes);
+ bm.setPixels(mask.fImage);
+
+ // need to copy for deferred drawing test to work
+ SkBitmap bm2;
+
+ bm.deepCopyTo(&bm2, SkBitmap::kA8_Config);
+
+ canvas->drawBitmap(bm2,
+ SK_Scalar1 * mask.fBounds.fLeft,
+ SK_Scalar1 * mask.fBounds.fTop,
+ &paint);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+/*
+ * This GM tests anti aliased single operation booleans with SkAAClips,
+ * SkRect and SkPaths.
+ */
+class SimpleClipGM : public GM {
+public:
+ enum SkGeomTypes {
+ kRect_GeomType,
+ kPath_GeomType,
+ kAAClip_GeomType
+ };
+
+ SimpleClipGM(SkGeomTypes geomType)
+ : fGeomType(geomType) {
+
+ // offset the rects a bit so we get anti-aliasing in the rect case
+ fBase.set(SkFloatToScalar(100.5f),
+ SkFloatToScalar(100.5f),
+ SkFloatToScalar(150.5f),
+ SkFloatToScalar(150.5f));
+ fRect = fBase;
+ fRect.inset(5, 5);
+ fRect.offset(25, 25);
+
+ fBasePath.addRoundRect(fBase, SkIntToScalar(5), SkIntToScalar(5));
+ fRectPath.addRoundRect(fRect, SkIntToScalar(5), SkIntToScalar(5));
+ INHERITED::setBGColor(0xFFDDDDDD);
+ }
+
+protected:
+ void buildRgn(SkAAClip* clip, SkRegion::Op op) {
+ clip->setPath(fBasePath, NULL, true);
+
+ SkAAClip clip2;
+ clip2.setPath(fRectPath, NULL, true);
+ clip->op(clip2, op);
+ }
+
+ void drawOrig(SkCanvas* canvas) {
+ SkPaint paint;
+
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setColor(SK_ColorBLACK);
+
+ canvas->drawRect(fBase, paint);
+ canvas->drawRect(fRect, paint);
+ }
+
+ void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
+
+ SkAAClip clip;
+
+ this->buildRgn(&clip, op);
+ this->drawOrig(canvas);
+
+ SkPaint paint;
+ paint.setColor(color);
+ paint_rgn(canvas, clip, paint);
+ }
+
+ void drawPathsOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
+
+ this->drawOrig(canvas);
+
+ canvas->save();
+
+ // create the clip mask with the supplied boolean op
+ if (kPath_GeomType == fGeomType) {
+ // path-based case
+ canvas->clipPath(fBasePath, SkRegion::kReplace_Op, true);
+ canvas->clipPath(fRectPath, op, true);
+ } else {
+ // rect-based case
+ canvas->clipRect(fBase, SkRegion::kReplace_Op, true);
+ canvas->clipRect(fRect, op, true);
+ }
+
+ // draw a rect that will entirely cover the clip mask area
+ SkPaint paint;
+ paint.setColor(color);
+
+ SkRect r = SkRect::MakeLTRB(SkIntToScalar(90), SkIntToScalar(90),
+ SkIntToScalar(180), SkIntToScalar(180));
+
+ canvas->drawRect(r, paint);
+
+ canvas->restore();
+ }
+
+ virtual SkString onShortName() {
+ SkString str;
+ str.printf("simpleaaclip_%s",
+ kRect_GeomType == fGeomType ? "rect" :
+ (kPath_GeomType == fGeomType ? "path" :
+ "aaclip"));
+ return str;
+ }
+
+ virtual SkISize onISize() {
+ return make_isize(640, 480);
+ }
+
+ virtual void onDraw(SkCanvas* canvas) {
+
+ static const struct {
+ SkColor fColor;
+ const char* fName;
+ SkRegion::Op fOp;
+ } gOps[] = {
+ { SK_ColorBLACK, "Difference", SkRegion::kDifference_Op },
+ { SK_ColorRED, "Intersect", SkRegion::kIntersect_Op },
+ { 0xFF008800, "Union", SkRegion::kUnion_Op },
+ { SK_ColorBLUE, "XOR", SkRegion::kXOR_Op },
+ { SK_ColorGREEN, "Rev Diff", SkRegion::kReverseDifference_Op },
+ { SK_ColorYELLOW, "Replace", SkRegion::kReplace_Op }
+ };
+
+ SkPaint textPaint;
+ textPaint.setAntiAlias(true);
+ textPaint.setTextSize(SK_Scalar1*24);
+
+ for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
+ canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
+ SkIntToScalar(75), SkIntToScalar(50),
+ textPaint);
+
+ if (kAAClip_GeomType == fGeomType) {
+ this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
+ } else {
+ this->drawPathsOped(canvas, gOps[op].fOp, gOps[op].fColor);
+ }
+
+ if (op && !(op % 3)) {
+ canvas->translate(SkIntToScalar(-600), SkIntToScalar(250));
+ } else {
+ canvas->translate(SkIntToScalar(200), 0);
+ }
+ }
+ }
+private:
+
+ SkGeomTypes fGeomType;
+
+ SkRect fBase;
+ SkRect fRect;
+
+ SkPath fBasePath; // fBase as a round rect
+ SkPath fRectPath; // fRect as a round rect
+
+ typedef GM INHERITED;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+// rects
+static GM* MyFactory(void*) { return new SimpleClipGM(
+ SimpleClipGM::kRect_GeomType); }
+static GMRegistry reg(MyFactory);
+
+// paths
+static GM* MyFactory2(void*) { return new SimpleClipGM(
+ SimpleClipGM::kPath_GeomType); }
+static GMRegistry reg2(MyFactory2);
+
+// aa clip
+static GM* MyFactory3(void*) { return new SimpleClipGM(
+ SimpleClipGM::kAAClip_GeomType); }
+static GMRegistry reg3(MyFactory3);
+
+}