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 "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 
     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 
     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 
     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 
     76 static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize) {
     77     return newSize * radius / oldSize;
     78 }
     79 
     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 
    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 
    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:
    127     RRectGM() {}
    128 
    129 protected:
    130 
    131     SkString onShortName() override {
    132         return SkString("rrect");
    133     }
    134 
    135     SkISize onISize() override {
    136         return SkISize::Make(820, 710);
    137     }
    138 
    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