• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkCanvas.h"
10 #include "SkRRect.h"
11 #include "SkPath.h"
12 
13 typedef void (*InsetProc)(const SkRRect&, SkScalar dx, SkScalar dy, SkRRect*);
14 
inset0(const SkRRect & src,SkScalar dx,SkScalar dy,SkRRect * dst)15 static void inset0(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
16     SkRect r = src.rect();
17 
18     r.inset(dx, dy);
19     if (r.isEmpty()) {
20         dst->setEmpty();
21         return;
22     }
23 
24     SkVector radii[4];
25     for (int i = 0; i < 4; ++i) {
26         radii[i] = src.radii((SkRRect::Corner)i);
27     }
28     for (int i = 0; i < 4; ++i) {
29         radii[i].fX -= dx;
30         radii[i].fY -= dy;
31     }
32     dst->setRectRadii(r, radii);
33 }
34 
inset1(const SkRRect & src,SkScalar dx,SkScalar dy,SkRRect * dst)35 static void inset1(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
36     SkRect r = src.rect();
37 
38     r.inset(dx, dy);
39     if (r.isEmpty()) {
40         dst->setEmpty();
41         return;
42     }
43 
44     SkVector radii[4];
45     for (int i = 0; i < 4; ++i) {
46         radii[i] = src.radii((SkRRect::Corner)i);
47     }
48     dst->setRectRadii(r, radii);
49 }
50 
inset2(const SkRRect & src,SkScalar dx,SkScalar dy,SkRRect * dst)51 static void inset2(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
52     SkRect r = src.rect();
53 
54     r.inset(dx, dy);
55     if (r.isEmpty()) {
56         dst->setEmpty();
57         return;
58     }
59 
60     SkVector radii[4];
61     for (int i = 0; i < 4; ++i) {
62         radii[i] = src.radii((SkRRect::Corner)i);
63     }
64     for (int i = 0; i < 4; ++i) {
65         if (radii[i].fX) {
66             radii[i].fX -= dx;
67         }
68         if (radii[i].fY) {
69             radii[i].fY -= dy;
70         }
71     }
72     dst->setRectRadii(r, radii);
73 }
74 
prop(SkScalar radius,SkScalar newSize,SkScalar oldSize)75 static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize) {
76     return newSize * radius / oldSize;
77 }
78 
inset3(const SkRRect & src,SkScalar dx,SkScalar dy,SkRRect * dst)79 static void inset3(const SkRRect& src, SkScalar dx, SkScalar dy, SkRRect* dst) {
80     SkRect r = src.rect();
81 
82     r.inset(dx, dy);
83     if (r.isEmpty()) {
84         dst->setEmpty();
85         return;
86     }
87 
88     SkVector radii[4];
89     for (int i = 0; i < 4; ++i) {
90         radii[i] = src.radii((SkRRect::Corner)i);
91     }
92     for (int i = 0; i < 4; ++i) {
93         radii[i].fX = prop(radii[i].fX, r.width(), src.rect().width());
94         radii[i].fY = prop(radii[i].fY, r.height(), src.rect().height());
95     }
96     dst->setRectRadii(r, radii);
97 }
98 
draw_rrect_color(SkCanvas * canvas,const SkRRect & rrect)99 static void draw_rrect_color(SkCanvas* canvas, const SkRRect& rrect) {
100     SkPaint paint;
101     paint.setAntiAlias(true);
102     paint.setStyle(SkPaint::kStroke_Style);
103 
104     if (rrect.isRect()) {
105         paint.setColor(SK_ColorRED);
106     } else if (rrect.isOval()) {
107         paint.setColor(0xFF008800);
108     } else if (rrect.isSimple()) {
109         paint.setColor(SK_ColorBLUE);
110     } else {
111         paint.setColor(SK_ColorBLACK);
112     }
113     canvas->drawRRect(rrect, paint);
114 }
115 
drawrr(SkCanvas * canvas,const SkRRect & rrect,InsetProc proc)116 static void drawrr(SkCanvas* canvas, const SkRRect& rrect, InsetProc proc) {
117     SkRRect rr;
118     for (SkScalar d = -30; d <= 30; d += 5) {
119         proc(rrect, d, d, &rr);
120         draw_rrect_color(canvas, rr);
121     }
122 }
123 
124 class RRectGM : public skiagm::GM {
125 public:
RRectGM()126     RRectGM() {}
127 
128 protected:
onGetFlags() const129     virtual uint32_t onGetFlags() const SK_OVERRIDE {
130         return kSkipTiled_Flag;
131     }
132 
onShortName()133     virtual SkString onShortName() {
134         return SkString("rrect");
135     }
136 
onISize()137     virtual SkISize onISize() {
138         return SkISize::Make(820, 710);
139     }
140 
onDraw(SkCanvas * canvas)141     virtual void onDraw(SkCanvas* canvas) {
142         static const InsetProc insetProcs[] = {
143             inset0, inset1, inset2, inset3
144         };
145 
146         SkRRect rrect[4];
147         SkRect r = { 0, 0, 120, 100 };
148         SkVector radii[4] = {
149             { 0, 0 }, { 30, 1 }, { 10, 40 }, { 40, 40 }
150         };
151 
152         rrect[0].setRect(r);
153         rrect[1].setOval(r);
154         rrect[2].setRectXY(r, 20, 20);
155         rrect[3].setRectRadii(r, radii);
156 
157         canvas->translate(50.5f, 50.5f);
158         for (size_t j = 0; j < SK_ARRAY_COUNT(insetProcs); ++j) {
159             canvas->save();
160             for (size_t i = 0; i < SK_ARRAY_COUNT(rrect); ++i) {
161                 drawrr(canvas, rrect[i], insetProcs[j]);
162                 canvas->translate(200, 0);
163             }
164             canvas->restore();
165             canvas->translate(0, 170);
166         }
167     }
168 
169 private:
170     typedef GM INHERITED;
171 };
172 
173 DEF_GM( return new RRectGM; )
174