Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2014 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 #include "gm.h"
      8 #include "sk_tool_utils.h"
      9 #include "SkCanvas.h"
     10 #include "SkPath.h"
     11 
     12 namespace skiagm {
     13 
     14 constexpr SkColor gPathColor = SK_ColorYELLOW;
     15 
     16 class ComplexClip3GM : public GM {
     17 public:
     18     ComplexClip3GM(bool doSimpleClipFirst)
     19         : fDoSimpleClipFirst(doSimpleClipFirst) {
     20         this->setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
     21     }
     22 
     23 protected:
     24 
     25     SkString onShortName() {
     26         SkString str;
     27         str.printf("complexclip3_%s", fDoSimpleClipFirst ? "simple" : "complex");
     28         return str;
     29     }
     30 
     31     SkISize onISize() { return SkISize::Make(1000, 950); }
     32 
     33     virtual void onDraw(SkCanvas* canvas) {
     34         SkPath clipSimple;
     35         clipSimple.addCircle(SkIntToScalar(70), SkIntToScalar(50), SkIntToScalar(20));
     36 
     37         SkRect r1 = { 10, 20, 70, 80 };
     38         SkPath clipComplex;
     39         clipComplex.moveTo(SkIntToScalar(40),  SkIntToScalar(50));
     40         clipComplex.arcTo(r1, SkIntToScalar(30), SkIntToScalar(300), false);
     41         clipComplex.close();
     42 
     43         SkPath* firstClip = &clipSimple;
     44         SkPath* secondClip = &clipComplex;
     45 
     46         if (!fDoSimpleClipFirst) {
     47             SkTSwap<SkPath*>(firstClip, secondClip);
     48         }
     49 
     50         SkPaint paint;
     51         paint.setAntiAlias(true);
     52         sk_tool_utils::set_portable_typeface(&paint);
     53         paint.setTextSize(SkIntToScalar(20));
     54 
     55         constexpr struct {
     56             SkClipOp    fOp;
     57             const char* fName;
     58         } gOps[] = {
     59             {kIntersect_SkClipOp,         "I"},
     60             {kDifference_SkClipOp,        "D" },
     61             {kUnion_SkClipOp,             "U"},
     62             {kXOR_SkClipOp,               "X"  },
     63             {kReverseDifference_SkClipOp, "R"}
     64         };
     65 
     66         canvas->translate(SkIntToScalar(20), SkIntToScalar(20));
     67         canvas->scale(3 * SK_Scalar1 / 4, 3 * SK_Scalar1 / 4);
     68 
     69         SkPaint pathPaint;
     70         pathPaint.setAntiAlias(true);
     71         pathPaint.setColor(gPathColor);
     72 
     73         for (int invA = 0; invA < 2; ++invA) {
     74             for (int aaBits = 0; aaBits < 4; ++aaBits) {
     75                 canvas->save();
     76                 for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); ++op) {
     77                     for (int invB = 0; invB < 2; ++invB) {
     78                         bool doAAA = SkToBool(aaBits & 1);
     79                         bool doAAB = SkToBool(aaBits & 2);
     80                         bool doInvA = SkToBool(invA);
     81                         bool doInvB = SkToBool(invB);
     82                         canvas->save();
     83                         // set clip
     84                         firstClip->setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType :
     85                                                SkPath::kEvenOdd_FillType);
     86                         secondClip->setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType :
     87                                                 SkPath::kEvenOdd_FillType);
     88                         canvas->clipPath(*firstClip, doAAA);
     89                         canvas->clipPath(*secondClip, gOps[op].fOp, doAAB);
     90 
     91                         // draw rect clipped
     92                         SkRect r = { 0, 0, 100, 100 };
     93                         canvas->drawRect(r, pathPaint);
     94                         canvas->restore();
     95 
     96 
     97                         SkScalar txtX = SkIntToScalar(10);
     98                         paint.setColor(SK_ColorBLACK);
     99                         SkString str;
    100                         str.printf("%s%s %s %s%s", doAAA ? "A" : "B",
    101                                                    doInvA ? "I" : "N",
    102                                                    gOps[op].fName,
    103                                                    doAAB ? "A" : "B",
    104                                                    doInvB ? "I" : "N");
    105 
    106                         canvas->drawString(str.c_str(), txtX, SkIntToScalar(130), paint);
    107                         if (doInvB) {
    108                             canvas->translate(SkIntToScalar(150),0);
    109                         } else {
    110                             canvas->translate(SkIntToScalar(120),0);
    111                         }
    112                     }
    113                 }
    114                 canvas->restore();
    115                 canvas->translate(0, SkIntToScalar(150));
    116             }
    117         }
    118     }
    119 
    120 private:
    121     bool fDoSimpleClipFirst;
    122 
    123     typedef GM INHERITED;
    124 };
    125 
    126 //////////////////////////////////////////////////////////////////////////////
    127 
    128 // Simple clip first
    129 DEF_GM( return new ComplexClip3GM(true); )
    130 // Complex clip first
    131 DEF_GM( return new ComplexClip3GM(false); )
    132 }
    133