• 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