141 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			141 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright 2014 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/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/SkPathBuilder.h"
 | |
| #include "include/core/SkRect.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 "tools/ToolUtils.h"
 | |
| 
 | |
| #include <utility>
 | |
| 
 | |
| namespace skiagm {
 | |
| 
 | |
| constexpr SkColor gPathColor = SK_ColorYELLOW;
 | |
| 
 | |
| class ComplexClip3GM : public GM {
 | |
| public:
 | |
|     ComplexClip3GM(bool doSimpleClipFirst)
 | |
|         : fDoSimpleClipFirst(doSimpleClipFirst) {
 | |
|         this->setBGColor(0xFFDDDDDD);
 | |
|     }
 | |
| 
 | |
| protected:
 | |
| 
 | |
|     SkString onShortName() override {
 | |
|         SkString str;
 | |
|         str.printf("complexclip3_%s", fDoSimpleClipFirst ? "simple" : "complex");
 | |
|         return str;
 | |
|     }
 | |
| 
 | |
|     SkISize onISize() override { return SkISize::Make(400, 950); }
 | |
| 
 | |
|     void onDraw(SkCanvas* canvas) override {
 | |
|         SkPath clipSimple = SkPath::Circle(70, 50, 20);
 | |
| 
 | |
|         SkRect r1 = { 10, 20, 70, 80 };
 | |
|         SkPath clipComplex = SkPathBuilder().moveTo(40,  50)
 | |
|                                             .arcTo(r1, 30, 300, false)
 | |
|                                             .close()
 | |
|                                             .detach();
 | |
| 
 | |
|         SkPath* firstClip = &clipSimple;
 | |
|         SkPath* secondClip = &clipComplex;
 | |
|         if (!fDoSimpleClipFirst) {
 | |
|             std::swap(firstClip, secondClip);
 | |
|         }
 | |
| 
 | |
|         SkPaint paint;
 | |
|         paint.setAntiAlias(true);
 | |
| 
 | |
|         SkFont font(ToolUtils::create_portable_typeface(), 20);
 | |
| 
 | |
|         constexpr struct {
 | |
|             SkClipOp    fOp;
 | |
|             const char* fName;
 | |
|         } gOps[] = {
 | |
|             {SkClipOp::kIntersect,         "I"},
 | |
|             {SkClipOp::kDifference,        "D" },
 | |
|         };
 | |
| 
 | |
|         canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
 | |
|         canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
 | |
| 
 | |
|         SkPaint pathPaint;
 | |
|         pathPaint.setAntiAlias(true);
 | |
|         pathPaint.setColor(gPathColor);
 | |
| 
 | |
|         for (int invA = 0; invA < 2; ++invA) {
 | |
|             for (int aaBits = 0; aaBits < 4; ++aaBits) {
 | |
|                 canvas->save();
 | |
|                 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
 | |
|                     for (int invB = 0; invB < 2; ++invB) {
 | |
|                         bool doAAA = SkToBool(aaBits & 1);
 | |
|                         bool doAAB = SkToBool(aaBits & 2);
 | |
|                         bool doInvA = SkToBool(invA);
 | |
|                         bool doInvB = SkToBool(invB);
 | |
|                         canvas->save();
 | |
|                         // set clip
 | |
|                         firstClip->setFillType(doInvA ? SkPathFillType::kInverseEvenOdd :
 | |
|                                                SkPathFillType::kEvenOdd);
 | |
|                         secondClip->setFillType(doInvB ? SkPathFillType::kInverseEvenOdd :
 | |
|                                                 SkPathFillType::kEvenOdd);
 | |
|                         canvas->clipPath(*firstClip, doAAA);
 | |
|                         canvas->clipPath(*secondClip, gOps[op].fOp, doAAB);
 | |
| 
 | |
|                         // draw rect clipped
 | |
|                         SkRect r = { 0, 0, 100, 100 };
 | |
|                         canvas->drawRect(r, pathPaint);
 | |
|                         canvas->restore();
 | |
| 
 | |
| 
 | |
|                         SkScalar txtX = SkIntToScalar(10);
 | |
|                         paint.setColor(SK_ColorBLACK);
 | |
|                         SkString str;
 | |
|                         str.printf("%s%s %s %s%s", doAAA ? "A" : "B",
 | |
|                                                    doInvA ? "I" : "N",
 | |
|                                                    gOps[op].fName,
 | |
|                                                    doAAB ? "A" : "B",
 | |
|                                                    doInvB ? "I" : "N");
 | |
| 
 | |
|                         canvas->drawString(str.c_str(), txtX, SkIntToScalar(130), font, paint);
 | |
|                         if (doInvB) {
 | |
|                             canvas->translate(SkIntToScalar(150),0);
 | |
|                         } else {
 | |
|                             canvas->translate(SkIntToScalar(120),0);
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 canvas->restore();
 | |
|                 canvas->translate(0, SkIntToScalar(150));
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| 
 | |
| private:
 | |
|     bool fDoSimpleClipFirst;
 | |
| 
 | |
|     using INHERITED = GM;
 | |
| };
 | |
| 
 | |
| //////////////////////////////////////////////////////////////////////////////
 | |
| 
 | |
| // Simple clip first
 | |
| DEF_GM( return new ComplexClip3GM(true); )
 | |
| // Complex clip first
 | |
| DEF_GM( return new ComplexClip3GM(false); )
 | |
| }  // namespace skiagm
 |