Home | History | Annotate | Download | only in gm
      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 
     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 
     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 
     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 
     75 static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize) {
     76     return newSize * radius / oldSize;
     77 }
     78 
     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 
     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 
    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:
    126     RRectGM() {}
    127 
    128 protected:
    129     virtual uint32_t onGetFlags() const SK_OVERRIDE {
    130         return kSkipTiled_Flag;
    131     }
    132 
    133     virtual SkString onShortName() {
    134         return SkString("rrect");
    135     }
    136 
    137     virtual SkISize onISize() {
    138         return SkISize::Make(820, 710);
    139     }
    140 
    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