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