Home | History | Annotate | Download | only in gm
      1 
      2 /*
      3  * Copyright 2011 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 #include "gm.h"
      9 
     10 typedef SkScalar (*MakePathProc)(SkPath*);
     11 
     12 static SkScalar make_frame(SkPath* path) {
     13     SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
     14                  SkIntToScalar(630), SkIntToScalar(470) };
     15     path->addRoundRect(r, SkIntToScalar(15), SkIntToScalar(15));
     16 
     17     SkPaint paint;
     18     paint.setStyle(SkPaint::kStroke_Style);
     19     paint.setStrokeWidth(SkIntToScalar(5));
     20     paint.getFillPath(*path, path);
     21     return SkIntToScalar(15);
     22 }
     23 
     24 static SkScalar make_triangle(SkPath* path) {
     25     static const int gCoord[] = {
     26         10, 20, 15, 5, 30, 30
     27     };
     28     path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
     29     path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
     30     path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
     31     path->close();
     32     path->offset(SkIntToScalar(10), SkIntToScalar(0));
     33     return SkIntToScalar(30);
     34 }
     35 
     36 static SkScalar make_rect(SkPath* path) {
     37     SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
     38                  SkIntToScalar(30), SkIntToScalar(30) };
     39     path->addRect(r);
     40     path->offset(SkIntToScalar(10), SkIntToScalar(0));
     41     return SkIntToScalar(30);
     42 }
     43 
     44 static SkScalar make_oval(SkPath* path) {
     45     SkRect r = { SkIntToScalar(10), SkIntToScalar(10),
     46                  SkIntToScalar(30), SkIntToScalar(30) };
     47     path->addOval(r);
     48     path->offset(SkIntToScalar(10), SkIntToScalar(0));
     49     return SkIntToScalar(30);
     50 }
     51 
     52 static SkScalar make_sawtooth(SkPath* path) {
     53     SkScalar x = SkIntToScalar(20);
     54     SkScalar y = SkIntToScalar(20);
     55     const SkScalar x0 = x;
     56     const SkScalar dx = SK_Scalar1 * 5;
     57     const SkScalar dy = SK_Scalar1 * 10;
     58 
     59     path->moveTo(x, y);
     60     for (int i = 0; i < 32; i++) {
     61         x += dx;
     62         path->lineTo(x, y - dy);
     63         x += dx;
     64         path->lineTo(x, y + dy);
     65     }
     66     path->lineTo(x, y + (2 * dy));
     67     path->lineTo(x0, y + (2 * dy));
     68     path->close();
     69     return SkIntToScalar(30);
     70 }
     71 
     72 static SkScalar make_star(SkPath* path, int n) {
     73     const SkScalar c = SkIntToScalar(45);
     74     const SkScalar r = SkIntToScalar(20);
     75 
     76     SkScalar rad = -SK_ScalarPI / 2;
     77     const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
     78 
     79     path->moveTo(c, c - r);
     80     for (int i = 1; i < n; i++) {
     81         rad += drad;
     82         SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
     83         path->lineTo(c + SkScalarMul(cosV, r), c + SkScalarMul(sinV, r));
     84     }
     85     path->close();
     86     return r * 2 * 6 / 5;
     87 }
     88 
     89 static SkScalar make_star_5(SkPath* path) { return make_star(path, 5); }
     90 static SkScalar make_star_13(SkPath* path) { return make_star(path, 13); }
     91 
     92 // We don't expect any output from this path.
     93 static SkScalar make_line(SkPath* path) {
     94     path->moveTo(SkIntToScalar(30), SkIntToScalar(30));
     95     path->lineTo(SkIntToScalar(120), SkIntToScalar(40));
     96     path->close();
     97     path->moveTo(SkIntToScalar(150), SkIntToScalar(30));
     98     path->lineTo(SkIntToScalar(150), SkIntToScalar(30));
     99     path->lineTo(SkIntToScalar(300), SkIntToScalar(40));
    100     path->close();
    101     return SkIntToScalar(40);
    102 }
    103 
    104 static const MakePathProc gProcs[] = {
    105     make_frame,
    106     make_triangle,
    107     make_rect,
    108     make_oval,
    109     make_sawtooth,
    110     make_star_5,
    111     make_star_13,
    112     make_line,
    113 };
    114 
    115 #define N   SK_ARRAY_COUNT(gProcs)
    116 
    117 class PathFillGM : public skiagm::GM {
    118     SkPath  fPath[N];
    119     SkScalar fDY[N];
    120 public:
    121     PathFillGM() {
    122         for (size_t i = 0; i < N; i++) {
    123             fDY[i] = gProcs[i](&fPath[i]);
    124         }
    125     }
    126 
    127 protected:
    128     virtual SkString onShortName() {
    129         return SkString("pathfill");
    130     }
    131 
    132     virtual SkISize onISize() {
    133         return SkISize::Make(640, 480);
    134     }
    135 
    136     virtual void onDraw(SkCanvas* canvas) {
    137         SkPaint paint;
    138         paint.setAntiAlias(true);
    139 
    140         for (size_t i = 0; i < N; i++) {
    141             canvas->drawPath(fPath[i], paint);
    142             canvas->translate(SkIntToScalar(0), fDY[i]);
    143         }
    144     }
    145 
    146 private:
    147     typedef skiagm::GM INHERITED;
    148 };
    149 
    150 // test inverse-fill w/ a clip that completely excludes the geometry
    151 class PathInverseFillGM : public skiagm::GM {
    152     SkPath  fPath[N];
    153     SkScalar fDY[N];
    154 public:
    155     PathInverseFillGM() {
    156         for (size_t i = 0; i < N; i++) {
    157             fDY[i] = gProcs[i](&fPath[i]);
    158         }
    159     }
    160 
    161 protected:
    162     virtual SkString onShortName() {
    163         return SkString("pathinvfill");
    164     }
    165 
    166     virtual SkISize onISize() {
    167         return SkISize::Make(450, 220);
    168     }
    169 
    170     static void show(SkCanvas* canvas, const SkPath& path, const SkPaint& paint,
    171                      const SkRect* clip, SkScalar top, const SkScalar bottom) {
    172         canvas->save();
    173         if (clip) {
    174             SkRect r = *clip;
    175             r.fTop = top;
    176             r.fBottom = bottom;
    177             canvas->clipRect(r);
    178         }
    179         canvas->drawPath(path, paint);
    180         canvas->restore();
    181     }
    182 
    183     virtual void onDraw(SkCanvas* canvas) {
    184         SkPath path;
    185 
    186         path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
    187         path.toggleInverseFillType();
    188 
    189         SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
    190 
    191         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
    192 
    193         for (int doclip = 0; doclip <= 1; ++doclip) {
    194             for (int aa = 0; aa <= 1; ++aa) {
    195                 SkPaint paint;
    196                 paint.setAntiAlias(SkToBool(aa));
    197 
    198                 canvas->save();
    199                 canvas->clipRect(clipR);
    200 
    201                 const SkRect* clipPtr = doclip ? &clipR : NULL;
    202 
    203                 show(canvas, path, paint, clipPtr, clipR.fTop, clipR.centerY());
    204                 show(canvas, path, paint, clipPtr, clipR.centerY(), clipR.fBottom);
    205 
    206                 canvas->restore();
    207                 canvas->translate(SkIntToScalar(110), 0);
    208             }
    209         }
    210     }
    211 
    212 private:
    213     typedef skiagm::GM INHERITED;
    214 };
    215 
    216 ///////////////////////////////////////////////////////////////////////////////
    217 
    218 static skiagm::GM* MyFactory(void*) { return new PathFillGM; }
    219 static skiagm::GMRegistry reg(MyFactory);
    220 
    221 static skiagm::GM* F1(void*) { return new PathInverseFillGM; }
    222 static skiagm::GMRegistry gR1(F1);
    223