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 
      9 #include "gm.h"
     10 #include "SkCanvas.h"
     11 #include "SkAAClip.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.setConfig(SkBitmap::kA8_Config, mask.fBounds.width(),
     25                  mask.fBounds.height(), mask.fRowBytes);
     26     bm.setPixels(mask.fImage);
     27 
     28     // need to copy for deferred drawing test to work
     29     SkBitmap bm2;
     30 
     31     bm.deepCopyTo(&bm2, SkBitmap::kA8_Config);
     32 
     33     canvas->drawBitmap(bm2,
     34                        SK_Scalar1 * mask.fBounds.fLeft,
     35                        SK_Scalar1 * mask.fBounds.fTop,
     36                        &paint);
     37 }
     38 
     39 //////////////////////////////////////////////////////////////////////////////
     40 /*
     41  * This GM tests anti aliased single operation booleans with SkAAClips,
     42  * SkRect and SkPaths.
     43  */
     44 class SimpleClipGM : public GM {
     45 public:
     46     enum SkGeomTypes {
     47         kRect_GeomType,
     48         kPath_GeomType,
     49         kAAClip_GeomType
     50     };
     51 
     52     SimpleClipGM(SkGeomTypes geomType)
     53     : fGeomType(geomType) {
     54 
     55         // offset the rects a bit so we get anti-aliasing in the rect case
     56         fBase.set(SkFloatToScalar(100.65f),
     57                   SkFloatToScalar(100.65f),
     58                   SkFloatToScalar(150.65f),
     59                   SkFloatToScalar(150.65f));
     60         fRect = fBase;
     61         fRect.inset(5, 5);
     62         fRect.offset(25, 25);
     63 
     64         fBasePath.addRoundRect(fBase, SkIntToScalar(5), SkIntToScalar(5));
     65         fRectPath.addRoundRect(fRect, SkIntToScalar(5), SkIntToScalar(5));
     66         INHERITED::setBGColor(0xFFDDDDDD);
     67     }
     68 
     69 protected:
     70     void buildRgn(SkAAClip* clip, SkRegion::Op op) {
     71         clip->setPath(fBasePath, NULL, true);
     72 
     73         SkAAClip clip2;
     74         clip2.setPath(fRectPath, NULL, 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     virtual SkString onShortName() {
    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     virtual SkISize onISize() {
    139         return make_isize(640, 480);
    140     }
    141 
    142     virtual void onDraw(SkCanvas* canvas) {
    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             { 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         textPaint.setTextSize(SK_Scalar1*24);
    160         int xOff = 0;
    161 
    162         for (size_t op = 0; op < SK_ARRAY_COUNT(gOps); op++) {
    163             canvas->drawText(gOps[op].fName, strlen(gOps[op].fName),
    164                              SkIntToScalar(75), SkIntToScalar(50),
    165                              textPaint);
    166 
    167             if (kAAClip_GeomType == fGeomType) {
    168                 this->drawRgnOped(canvas, gOps[op].fOp, gOps[op].fColor);
    169             } else {
    170                 this->drawPathsOped(canvas, gOps[op].fOp, gOps[op].fColor);
    171             }
    172 
    173             if (xOff >= 400) {
    174                 canvas->translate(SkIntToScalar(-400), SkIntToScalar(250));
    175                 xOff = 0;
    176             } else {
    177                 canvas->translate(SkIntToScalar(200), 0);
    178                 xOff += 200;
    179             }
    180         }
    181     }
    182 private:
    183 
    184     SkGeomTypes fGeomType;
    185 
    186     SkRect fBase;
    187     SkRect fRect;
    188 
    189     SkPath fBasePath;       // fBase as a round rect
    190     SkPath fRectPath;       // fRect as a round rect
    191 
    192     typedef GM INHERITED;
    193 };
    194 
    195 //////////////////////////////////////////////////////////////////////////////
    196 
    197 // rects
    198 DEF_GM( return new SimpleClipGM(SimpleClipGM::kRect_GeomType); )
    199 DEF_GM( return new SimpleClipGM(SimpleClipGM::kPath_GeomType); )
    200 DEF_GM( return new SimpleClipGM(SimpleClipGM::kAAClip_GeomType); )
    201 
    202 }
    203