blob: 299e8d8d9b92d2f2193e85c96ad27c9d486d764b [file] [log] [blame]
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +00001/*
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
11namespace skiagm {
12
13///////////////////////////////////////////////////////////////////////////////
14
15class RRectGM : public GM {
16public:
17 RRectGM(bool doAA, bool doClip) : fDoAA(doAA), fDoClip(doClip) {
18 this->setBGColor(0xFFDDDDDD);
19 this->setUpRRects();
20 }
21
22protected:
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
skia.committer@gmail.com7a03d862012-12-18 02:03:03 +000043 paint.setAntiAlias(fDoClip ? false : fDoAA);
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +000044
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() {
skia.committer@gmail.com7a03d862012-12-18 02:03:03 +000070 // each RRect must fit in a 0x0 -> (kTileX-2)x(kTileY-2) block. These will be tiled across
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +000071 // 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]);
mike@reedtribe.orgf6100c82012-12-24 13:56:17 +000080 for (size_t i = 1; i < SK_ARRAY_COUNT(gRadii); ++i) {
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +000081 fRRects[kNumSimpleCases+i].setRectRadii(SkRect::MakeWH(kTileX-2, kTileY-2), gRadii[i]);
82 }
83 }
84
85private:
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;
robertphillips@google.com5683d422012-12-17 21:58:02 +000097 static const SkVector gRadii[kNumComplexCases][4];
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +000098
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
106const 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
143DEF_GM( return new RRectGM(false, false); )
144DEF_GM( return new RRectGM(true, false); )
145DEF_GM( return new RRectGM(false, true); )
146DEF_GM( return new RRectGM(true, true); )
147
148}