Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2012 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 
      8 #include "gm.h"
      9 #include "SkAAClip.h"
     10 #include "SkCanvas.h"
     11 #include "SkPath.h"
     12 
     13 namespace skiagm {
     14 
     15 static void paint_rgn(SkCanvas* canvas, const SkAAClip& clip,
     16                       const SkPaint& paint) {
     17     SkMask mask;
     18     SkBitmap bm;
     19 
     20     clip.copyToMask(&mask);
     21 
     22     SkAutoMaskFreeImage amfi(mask.fImage);
     23 
     24     bm.installMaskPixels(mask);
     25 
     26     // need to copy for deferred drawing test to work
     27     SkBitmap bm2;
     28 
     29     bm.deepCopyTo(&bm2);
     30 
     31     canvas->drawBitmap(bm2,
     32                        SK_Scalar1 * mask.fBounds.fLeft,
     33                        SK_Scalar1 * mask.fBounds.fTop,
     34                        &paint);
     35 }
     36 
     37 //////////////////////////////////////////////////////////////////////////////
     38 /*
     39  * This GM tests anti aliased single operation booleans with SkAAClips,
     40  * SkRect and SkPaths.
     41  */
     42 class SimpleClipGM : public GM {
     43 public:
     44     enum SkGeomTypes {
     45         kRect_GeomType,
     46         kPath_GeomType,
     47         kAAClip_GeomType
     48     };
     49 
     50     SimpleClipGM(SkGeomTypes geomType)
     51     : fGeomType(geomType) {
     52     }
     53 
     54 protected:
     55     void onOnceBeforeDraw() override {
     56         // offset the rects a bit so we get anti-aliasing in the rect case
     57         fBase.set(100.65f,
     58                   100.65f,
     59                   150.65f,
     60                   150.65f);
     61         fRect = fBase;
     62         fRect.inset(5, 5);
     63         fRect.offset(25, 25);
     64 
     65         fBasePath.addRoundRect(fBase, SkIntToScalar(5), SkIntToScalar(5));
     66         fRectPath.addRoundRect(fRect, SkIntToScalar(5), SkIntToScalar(5));
     67         INHERITED::setBGColor(sk_tool_utils::color_to_565(0xFFDDDDDD));
     68     }
     69 
     70     void buildRgn(SkAAClip* clip, SkRegion::Op op) {
     71         clip->setPath(fBasePath, nullptr, true);
     72 
     73         SkAAClip clip2;
     74         clip2.setPath(fRectPath, nullptr, true);
     75         clip->op(clip2, op);
     76     }
     77 
     78     void drawOrig(SkCanvas* canvas) {
     79         SkPaint     paint;
     80 
     81         paint.setStyle(SkPaint::kStroke_Style);
     82         paint.setColor(SK_ColorBLACK);
     83 
     84         canvas->drawRect(fBase, paint);
     85         canvas->drawRect(fRect, paint);
     86     }
     87 
     88     void drawRgnOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
     89 
     90         SkAAClip clip;
     91 
     92         this->buildRgn(&clip, op);
     93         this->drawOrig(canvas);
     94 
     95         SkPaint paint;
     96         paint.setColor(color);
     97         paint_rgn(canvas, clip, paint);
     98     }
     99 
    100     void drawPathsOped(SkCanvas* canvas, SkRegion::Op op, SkColor color) {
    101 
    102         this->drawOrig(canvas);
    103 
    104         canvas->save();
    105 
    106         // create the clip mask with the supplied boolean op
    107         if (kPath_GeomType == fGeomType) {
    108             // path-based case
    109             canvas->clipPath(fBasePath, SkRegion::kReplace_Op, true);
    110             canvas->clipPath(fRectPath, op, true);
    111         } else {
    112             // rect-based case
    113             canvas->clipRect(fBase, SkRegion::kReplace_Op, true);
    114             canvas->clipRect(fRect, op, true);
    115         }
    116 
    117         // draw a rect that will entirely cover the clip mask area
    118         SkPaint paint;
    119         paint.setColor(color);
    120 
    121         SkRect r = SkRect::MakeLTRB(SkIntToScalar(90),  SkIntToScalar(90),
    122                                     SkIntToScalar(180), SkIntToScalar(180));
    123 
    124         canvas->drawRect(r, paint);
    125 
    126         canvas->restore();
    127     }
    128 
    129     SkString onShortName() override {
    130         SkString str;
    131         str.printf("simpleaaclip_%s",
    132                     kRect_GeomType == fGeomType ? "rect" :
    133                     (kPath_GeomType == fGeomType ? "path" :
    134                     "aaclip"));
    135         return str;
    136     }
    137 
    138     SkISize onISize() override {
    139         return SkISize::Make(640, 480);
    140     }
    141 
    142     void onDraw(SkCanvas* canvas) override {
    143 
    144         static const struct {
    145             SkColor         fColor;
    146             const char*     fName;
    147             SkRegion::Op    fOp;
    148         } gOps[] = {
    149             { SK_ColorBLACK,    "Difference", SkRegion::kDifference_Op    },
    150             { SK_ColorRED,      "Intersect",  SkRegion::kIntersect_Op     },
    151             { sk_tool_utils::color_to_565(0xFF008800), "Union", SkRegion::kUnion_Op },
    152             { SK_ColorGREEN,    "Rev Diff",   SkRegion::kReverseDifference_Op },
    153             { SK_ColorYELLOW,   "Replace",    SkRegion::kReplace_Op       },
    154             { SK_ColorBLUE,     "XOR",        SkRegion::kXOR_Op           },
    155         };
    156 
    157         SkPaint textPaint;
    158         textPaint.setAntiAlias(true);
    159         sk_tool_utils::set_portable_typeface(&textPaint);
    160         textPaint.setTextSize(SK_Scalar1*24);
    161         int xOff = 0;
    162 
    163         for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
    164             canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
    165                              SkIntToScalar(75), SkIntToScalar(50),
    166                              textPaint);
    167 
    168             if (kAAClip_GeomType == fGeomType) {
    169                 this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
    170             } else {
    171                 this->drawPathsOped(canvas, gOps[op].fOp, gOps[op].fColor);
    172             }
    173 
    174             if (xOff >= 400) {
    175                 canvas->translate(SkIntToScalar(-400), SkIntToScalar(250));
    176                 xOff = 0;
    177             } else {
    178                 canvas->translate(SkIntToScalar(200), 0);
    179                 xOff += 200;
    180             }
    181         }
    182     }
    183 private:
    184 
    185     SkGeomTypes fGeomType;
    186 
    187     SkRect fBase;
    188     SkRect fRect;
    189 
    190     SkPath fBasePath;       // fBase as a round rect
    191     SkPath fRectPath;       // fRect as a round rect
    192 
    193     typedef GM INHERITED;
    194 };
    195 
    196 //////////////////////////////////////////////////////////////////////////////
    197 
    198 // rects
    199 DEF_GM( return new SimpleClipGM(SimpleClipGM::kRect_GeomType); )
    200 DEF_GM( return new SimpleClipGM(SimpleClipGM::kPath_GeomType); )
    201 DEF_GM( return new SimpleClipGM(SimpleClipGM::kAAClip_GeomType); )
    202 
    203 }
    204