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