xref: /third_party/skia/gm/rrect.cpp (revision cb93a386)
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
21typedef void (*InsetProc)(const SkRRect&, SkScalar dx, SkScalar dy, SkRRect*);
22
23static 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
43static 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
59static 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
83static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize) {
84    return newSize * radius / oldSize;
85}
86
87static 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
107static 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
124static 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
132class RRectGM : public skiagm::GM {
133public:
134    RRectGM() {}
135
136protected:
137
138    SkString onShortName() override {
139        return SkString("rrect");
140    }
141
142    SkISize onISize() override {
143        return SkISize::Make(820, 710);
144    }
145
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
174private:
175    using INHERITED = GM;
176};
177
178DEF_GM( return new RRectGM; )
179