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