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 "SkRRect.h"
     10 
     11 namespace skiagm {
     12 
     13 ///////////////////////////////////////////////////////////////////////////////
     14 
     15 class RRectGM : public GM {
     16 public:
     17     RRectGM(bool doAA, bool doClip) : fDoAA(doAA), fDoClip(doClip) {
     18         this->setBGColor(0xFFDDDDDD);
     19         this->setUpRRects();
     20     }
     21 
     22 protected:
     23     SkString onShortName() {
     24         SkString name("rrect");
     25         if (fDoClip) {
     26             name.append("_clip");
     27         }
     28         if (fDoAA) {
     29             name.append("_aa");
     30         } else {
     31             name.append("_bw");
     32         }
     33 
     34         return name;
     35     }
     36 
     37     virtual SkISize onISize() { return make_isize(kImageWidth, kImageHeight); }
     38 
     39     virtual void onDraw(SkCanvas* canvas) {
     40 
     41         SkPaint paint;
     42         // when clipping the AA is pushed into the clip operation
     43         paint.setAntiAlias(fDoClip ? false : fDoAA);
     44 
     45         static const SkRect kMaxTileBound = SkRect::MakeWH(SkIntToScalar(kTileX), SkIntToScalar(kTileY));
     46 
     47         int curRRect = 0;
     48         for (int y = 1; y < kImageHeight; y += kTileY) {
     49             for (int x = 1; x < kImageWidth; x += kTileX) {
     50                 if (curRRect >= kNumRRects) {
     51                     break;
     52                 }
     53                 SkASSERT(kMaxTileBound.contains(fRRects[curRRect].getBounds()));
     54 
     55                 canvas->save();
     56                     canvas->translate(SkIntToScalar(x), SkIntToScalar(y));
     57                     if (fDoClip) {
     58                         canvas->clipRRect(fRRects[curRRect], SkRegion::kReplace_Op, fDoAA);
     59                         canvas->drawRect(kMaxTileBound, paint);
     60                     } else {
     61                         canvas->drawRRect(fRRects[curRRect], paint);
     62                     }
     63                     ++curRRect;
     64                 canvas->restore();
     65             }
     66         }
     67     }
     68 
     69     void setUpRRects() {
     70         // each RRect must fit in a 0x0 -> (kTileX-2)x(kTileY-2) block. These will be tiled across
     71         // the screen in kTileX x kTileY tiles. The extra empty pixels on each side are for AA.
     72 
     73         // simple cases
     74         fRRects[0].setRect(SkRect::MakeWH(kTileX-2, kTileY-2));
     75         fRRects[1].setOval(SkRect::MakeWH(kTileX-2, kTileY-2));
     76         fRRects[2].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 10, 10);
     77 
     78         // The first complex case needs special handling since it is a square
     79         fRRects[kNumSimpleCases].setRectRadii(SkRect::MakeWH(kTileY-2, kTileY-2), gRadii[0]);
     80         for (size_t i = 1; i < SK_ARRAY_COUNT(gRadii); ++i) {
     81             fRRects[kNumSimpleCases+i].setRectRadii(SkRect::MakeWH(kTileX-2, kTileY-2), gRadii[i]);
     82         }
     83     }
     84 
     85 private:
     86     bool fDoAA;
     87     bool fDoClip;   // use clipRRect & drawRect instead of drawRRect
     88 
     89     static const int kImageWidth = 640;
     90     static const int kImageHeight = 480;
     91 
     92     static const int kTileX = 80;
     93     static const int kTileY = 40;
     94 
     95     static const int kNumSimpleCases = 3;
     96     static const int kNumComplexCases = 19;
     97     static const SkVector gRadii[kNumComplexCases][4];
     98 
     99     static const int kNumRRects = kNumSimpleCases + kNumComplexCases;
    100     SkRRect fRRects[kNumRRects];
    101 
    102     typedef GM INHERITED;
    103 };
    104 
    105 // Radii for the various test cases. Order is UL, UR, LR, LL
    106 const SkVector RRectGM::gRadii[kNumComplexCases][4] = {
    107     // a circle
    108     { { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY } },
    109 
    110     // odd ball cases
    111     { { 8, 8 }, { 32, 32 }, { 8, 8 }, { 32, 32 } },
    112     { { 16, 8 }, { 8, 16 }, { 16, 8 }, { 8, 16 } },
    113     { { 0, 0 }, { 16, 16 }, { 8, 8 }, { 32, 32 } },
    114 
    115     // UL
    116     { { 30, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
    117     { { 30, 15 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
    118     { { 15, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
    119 
    120     // UR
    121     { { 0, 0 }, { 30, 30 }, { 0, 0 }, { 0, 0 } },
    122     { { 0, 0 }, { 30, 15 }, { 0, 0 }, { 0, 0 } },
    123     { { 0, 0 }, { 15, 30 }, { 0, 0 }, { 0, 0 } },
    124 
    125     // LR
    126     { { 0, 0 }, { 0, 0 }, { 30, 30 }, { 0, 0 } },
    127     { { 0, 0 }, { 0, 0 }, { 30, 15 }, { 0, 0 } },
    128     { { 0, 0 }, { 0, 0 }, { 15, 30 }, { 0, 0 } },
    129 
    130     // LL
    131     { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 30 } },
    132     { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 15 } },
    133     { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 15, 30 } },
    134 
    135     // over-sized radii
    136     { { 0, 0 }, { 100, 400 }, { 0, 0 }, { 0, 0 } },
    137     { { 0, 0 }, { 400, 400 }, { 0, 0 }, { 0, 0 } },
    138     { { 400, 400 }, { 400, 400 }, { 400, 400 }, { 400, 400 } },
    139 };
    140 
    141 ///////////////////////////////////////////////////////////////////////////////
    142 
    143 DEF_GM( return new RRectGM(false, false); )
    144 DEF_GM( return new RRectGM(true, false); )
    145 DEF_GM( return new RRectGM(false, true); )
    146 DEF_GM( return new RRectGM(true, true); )
    147 
    148 }
    149