From 67febd9506629568d6e63b4a9e673ace4b42fa2a Mon Sep 17 00:00:00 2001 From: "robertphillips@google.com" Date: Tue, 22 May 2012 12:14:50 +0000 Subject: 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 --- gm/simpleaaclip.cpp | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 gm/simpleaaclip.cpp (limited to 'gm/simpleaaclip.cpp') diff --git a/gm/simpleaaclip.cpp b/gm/simpleaaclip.cpp new file mode 100644 index 0000000000..6873816b20 --- /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); + +} -- cgit v1.2.3