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 uint32_t onGetFlags() const SK_OVERRIDE {
    129         return kSkipTiled_Flag;
    130     }
    131 
    132     virtual SkString onShortName() {
    133         return SkString("pathfill");
    134     }
    135 
    136     virtual SkISize onISize() {
    137         return SkISize::Make(640, 480);
    138     }
    139 
    140     virtual void onDraw(SkCanvas* canvas) {
    141         SkPaint paint;
    142         paint.setAntiAlias(true);
    143 
    144         for (size_t i = 0; i < N; i++) {
    145             canvas->drawPath(fPath[i], paint);
    146             canvas->translate(SkIntToScalar(0), fDY[i]);
    147         }
    148     }
    149 
    150 private:
    151     typedef skiagm::GM INHERITED;
    152 };
    153 
    154 // test inverse-fill w/ a clip that completely excludes the geometry
    155 class PathInverseFillGM : public skiagm::GM {
    156     SkPath  fPath[N];
    157     SkScalar fDY[N];
    158 public:
    159     PathInverseFillGM() {
    160         for (size_t i = 0; i < N; i++) {
    161             fDY[i] = gProcs[i](&fPath[i]);
    162         }
    163     }
    164 
    165 protected:
    166     virtual uint32_t onGetFlags() const SK_OVERRIDE {
    167         return kSkipTiled_Flag;
    168     }
    169 
    170     virtual SkString onShortName() {
    171         return SkString("pathinvfill");
    172     }
    173 
    174     virtual SkISize onISize() {
    175         return SkISize::Make(450, 220);
    176     }
    177 
    178     static void show(SkCanvas* canvas, const SkPath& path, const SkPaint& paint,
    179                      const SkRect* clip, SkScalar top, const SkScalar bottom) {
    180         canvas->save();
    181         if (clip) {
    182             SkRect r = *clip;
    183             r.fTop = top;
    184             r.fBottom = bottom;
    185             canvas->clipRect(r);
    186         }
    187         canvas->drawPath(path, paint);
    188         canvas->restore();
    189     }
    190 
    191     virtual void onDraw(SkCanvas* canvas) {
    192         SkPath path;
    193 
    194         path.addCircle(SkIntToScalar(50), SkIntToScalar(50), SkIntToScalar(40));
    195         path.toggleInverseFillType();
    196 
    197         SkRect clipR = { 0, 0, SkIntToScalar(100), SkIntToScalar(200) };
    198 
    199         canvas->translate(SkIntToScalar(10), SkIntToScalar(10));
    200 
    201         for (int doclip = 0; doclip <= 1; ++doclip) {
    202             for (int aa = 0; aa <= 1; ++aa) {
    203                 SkPaint paint;
    204                 paint.setAntiAlias(SkToBool(aa));
    205 
    206                 canvas->save();
    207                 canvas->clipRect(clipR);
    208 
    209                 const SkRect* clipPtr = doclip ? &clipR : NULL;
    210 
    211                 show(canvas, path, paint, clipPtr, clipR.fTop, clipR.centerY());
    212                 show(canvas, path, paint, clipPtr, clipR.centerY(), clipR.fBottom);
    213 
    214                 canvas->restore();
    215                 canvas->translate(SkIntToScalar(110), 0);
    216             }
    217         }
    218     }
    219 
    220 private:
    221     typedef skiagm::GM INHERITED;
    222 };
    223 
    224 ///////////////////////////////////////////////////////////////////////////////
    225 
    226 static skiagm::GM* MyFactory(void*) { return new PathFillGM; }
    227 static skiagm::GMRegistry reg(MyFactory);
    228 
    229 static skiagm::GM* F1(void*) { return new PathInverseFillGM; }
    230 static skiagm::GMRegistry gR1(F1);
    231