blob: 9e07703b4395ec387bc77570d4bdce2add5a0e61 [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);
commit-bot@chromium.orgc2f78242014-02-19 15:18:05 +000077 fRRects[3].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 10, 5);
78 // small circular corners are an interesting test case for gpu clipping
79 fRRects[4].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 1, 1);
80 fRRects[5].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 0.5f, 0.5f);
81 fRRects[6].setRectXY(SkRect::MakeWH(kTileX-2, kTileY-2), 0.2f, 0.2f);
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +000082
83 // The first complex case needs special handling since it is a square
84 fRRects[kNumSimpleCases].setRectRadii(SkRect::MakeWH(kTileY-2, kTileY-2), gRadii[0]);
mike@reedtribe.orgf6100c82012-12-24 13:56:17 +000085 for (size_t i = 1; i < SK_ARRAY_COUNT(gRadii); ++i) {
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +000086 fRRects[kNumSimpleCases+i].setRectRadii(SkRect::MakeWH(kTileX-2, kTileY-2), gRadii[i]);
87 }
88 }
89
90private:
91 bool fDoAA;
92 bool fDoClip; // use clipRRect & drawRect instead of drawRRect
93
94 static const int kImageWidth = 640;
95 static const int kImageHeight = 480;
96
97 static const int kTileX = 80;
98 static const int kTileY = 40;
99
commit-bot@chromium.orgc2f78242014-02-19 15:18:05 +0000100 static const int kNumSimpleCases = 7;
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +0000101 static const int kNumComplexCases = 19;
robertphillips@google.com5683d422012-12-17 21:58:02 +0000102 static const SkVector gRadii[kNumComplexCases][4];
robertphillips@google.com4e18c7a2012-12-17 21:48:19 +0000103
104 static const int kNumRRects = kNumSimpleCases + kNumComplexCases;
105 SkRRect fRRects[kNumRRects];
106
107 typedef GM INHERITED;
108};
109
110// Radii for the various test cases. Order is UL, UR, LR, LL
111const SkVector RRectGM::gRadii[kNumComplexCases][4] = {
112 // a circle
113 { { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY }, { kTileY, kTileY } },
114
115 // odd ball cases
116 { { 8, 8 }, { 32, 32 }, { 8, 8 }, { 32, 32 } },
117 { { 16, 8 }, { 8, 16 }, { 16, 8 }, { 8, 16 } },
118 { { 0, 0 }, { 16, 16 }, { 8, 8 }, { 32, 32 } },
119
120 // UL
121 { { 30, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
122 { { 30, 15 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
123 { { 15, 30 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
124
125 // UR
126 { { 0, 0 }, { 30, 30 }, { 0, 0 }, { 0, 0 } },
127 { { 0, 0 }, { 30, 15 }, { 0, 0 }, { 0, 0 } },
128 { { 0, 0 }, { 15, 30 }, { 0, 0 }, { 0, 0 } },
129
130 // LR
131 { { 0, 0 }, { 0, 0 }, { 30, 30 }, { 0, 0 } },
132 { { 0, 0 }, { 0, 0 }, { 30, 15 }, { 0, 0 } },
133 { { 0, 0 }, { 0, 0 }, { 15, 30 }, { 0, 0 } },
134
135 // LL
136 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 30 } },
137 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 30, 15 } },
138 { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 15, 30 } },
139
140 // over-sized radii
141 { { 0, 0 }, { 100, 400 }, { 0, 0 }, { 0, 0 } },
142 { { 0, 0 }, { 400, 400 }, { 0, 0 }, { 0, 0 } },
143 { { 400, 400 }, { 400, 400 }, { 400, 400 }, { 400, 400 } },
144};
145
146///////////////////////////////////////////////////////////////////////////////
147
148DEF_GM( return new RRectGM(false, false); )
149DEF_GM( return new RRectGM(true, false); )
150DEF_GM( return new RRectGM(false, true); )
151DEF_GM( return new RRectGM(true, true); )
152
153}