| /* | 
 |  * 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/gm.h" | 
 | #include "include/core/SkBitmap.h" | 
 | #include "include/core/SkCanvas.h" | 
 | #include "include/core/SkClipOp.h" | 
 | #include "include/core/SkColor.h" | 
 | #include "include/core/SkFont.h" | 
 | #include "include/core/SkPaint.h" | 
 | #include "include/core/SkPath.h" | 
 | #include "include/core/SkRect.h" | 
 | #include "include/core/SkRegion.h" | 
 | #include "include/core/SkScalar.h" | 
 | #include "include/core/SkSize.h" | 
 | #include "include/core/SkString.h" | 
 | #include "include/core/SkTypeface.h" | 
 | #include "include/core/SkTypes.h" | 
 | #include "src/core/SkAAClip.h" | 
 | #include "src/core/SkClipOpPriv.h" | 
 | #include "src/core/SkMask.h" | 
 | #include "tools/ToolUtils.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.installMaskPixels(mask); | 
 |  | 
 |     // need to copy for deferred drawing test to work | 
 |     SkBitmap bm2; | 
 |  | 
 |     ToolUtils::copy_to(&bm2, bm.colorType(), bm); | 
 |  | 
 |     canvas->drawImage(bm2.asImage(), | 
 |                       SK_Scalar1 * mask.fBounds.fLeft, | 
 |                       SK_Scalar1 * mask.fBounds.fTop, | 
 |                       SkSamplingOptions(), | 
 |                       &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) { | 
 |     } | 
 |  | 
 | protected: | 
 |     void onOnceBeforeDraw() override { | 
 |         // offset the rects a bit so we get anti-aliasing in the rect case | 
 |         fBase.setLTRB(100.65f, | 
 |                       100.65f, | 
 |                       150.65f, | 
 |                       150.65f); | 
 |         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); | 
 |     } | 
 |  | 
 |     void buildRgn(SkAAClip* clip, SkClipOp op) { | 
 |         clip->setPath(fBasePath, nullptr, true); | 
 |  | 
 |         SkAAClip clip2; | 
 |         clip2.setPath(fRectPath, nullptr, true); | 
 |         clip->op(clip2, (SkRegion::Op)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, SkClipOp 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, SkClipOp 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, true); | 
 |             canvas->clipPath(fRectPath, op, true); | 
 |         } else { | 
 |             // rect-based case | 
 |             canvas->clipRect(fBase, 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(); | 
 |     } | 
 |  | 
 |     SkString onShortName() override { | 
 |         SkString str; | 
 |         str.printf("simpleaaclip_%s", | 
 |                     kRect_GeomType == fGeomType ? "rect" : | 
 |                     (kPath_GeomType == fGeomType ? "path" : | 
 |                     "aaclip")); | 
 |         return str; | 
 |     } | 
 |  | 
 |     SkISize onISize() override { | 
 |         return SkISize::Make(500, 240); | 
 |     } | 
 |  | 
 |     void onDraw(SkCanvas* canvas) override { | 
 |  | 
 |         const struct { | 
 |             SkColor         fColor; | 
 |             const char*     fName; | 
 |             SkClipOp        fOp; | 
 |         } gOps[] = { | 
 |                 {SK_ColorBLACK, "Difference", kDifference_SkClipOp}, | 
 |                 {SK_ColorRED, "Intersect", kIntersect_SkClipOp}, | 
 |         }; | 
 |  | 
 |         SkPaint textPaint; | 
 |         SkFont  font(ToolUtils::create_portable_typeface(), 24); | 
 |         int xOff = 0; | 
 |  | 
 |         for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) { | 
 |             canvas->drawString(gOps[op].fName, 75.0f, 50.0f, font, 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 (xOff >= 400) { | 
 |                 canvas->translate(SkIntToScalar(-400), SkIntToScalar(250)); | 
 |                 xOff = 0; | 
 |             } else { | 
 |                 canvas->translate(SkIntToScalar(200), 0); | 
 |                 xOff += 200; | 
 |             } | 
 |         } | 
 |     } | 
 | private: | 
 |  | 
 |     SkGeomTypes fGeomType; | 
 |  | 
 |     SkRect fBase; | 
 |     SkRect fRect; | 
 |  | 
 |     SkPath fBasePath;       // fBase as a round rect | 
 |     SkPath fRectPath;       // fRect as a round rect | 
 |  | 
 |     using INHERITED = GM; | 
 | }; | 
 |  | 
 | ////////////////////////////////////////////////////////////////////////////// | 
 |  | 
 | // rects | 
 | DEF_GM( return new SimpleClipGM(SimpleClipGM::kRect_GeomType); ) | 
 | DEF_GM( return new SimpleClipGM(SimpleClipGM::kPath_GeomType); ) | 
 | DEF_GM( return new SimpleClipGM(SimpleClipGM::kAAClip_GeomType); ) | 
 |  | 
 | }  // namespace skiagm |