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