211 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			211 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * 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/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, fBasePath.getBounds().roundOut(), true);
 | |
| 
 | |
|         SkAAClip clip2;
 | |
|         clip2.setPath(fRectPath, fRectPath.getBounds().roundOut(), 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, 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", SkClipOp::kDifference},
 | |
|                 {SK_ColorRED, "Intersect", SkClipOp::kIntersect},
 | |
|         };
 | |
| 
 | |
|         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
 |