Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2013 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 "SkTArray.h"
     11 
     12 namespace skiagm {
     13 
     14 class ConicPathsGM : public GM {
     15 protected:
     16 
     17     virtual SkString onShortName() SK_OVERRIDE {
     18         return SkString("conicpaths");
     19     }
     20 
     21     virtual SkISize onISize() SK_OVERRIDE {
     22         return SkISize::Make(1000, 1000);
     23     }
     24 
     25     virtual void onOnceBeforeDraw() SK_OVERRIDE {
     26         {
     27             SkPath* conicCirlce = &fPaths.push_back();
     28             conicCirlce->moveTo(0, -0);
     29             conicCirlce->conicTo(SkIntToScalar(0), SkIntToScalar(50),
     30                                         SkIntToScalar(50), SkIntToScalar(50),
     31                                         SkScalarHalf(SkScalarSqrt(2)));
     32             conicCirlce->rConicTo(SkIntToScalar(50), SkIntToScalar(0),
     33                                          SkIntToScalar(50), SkIntToScalar(-50),
     34                                          SkScalarHalf(SkScalarSqrt(2)));
     35             conicCirlce->rConicTo(SkIntToScalar(0), SkIntToScalar(-50),
     36                                          SkIntToScalar(-50), SkIntToScalar(-50),
     37                                          SkScalarHalf(SkScalarSqrt(2)));
     38             conicCirlce->rConicTo(SkIntToScalar(-50), SkIntToScalar(0),
     39                                          SkIntToScalar(-50), SkIntToScalar(50),
     40                                          SkScalarHalf(SkScalarSqrt(2)));
     41 
     42         }
     43         {
     44             SkPath* hyperbola = &fPaths.push_back();
     45             hyperbola->moveTo(0, -0);
     46             hyperbola->conicTo(SkIntToScalar(0), SkIntToScalar(100),
     47                                         SkIntToScalar(100), SkIntToScalar(100),
     48                                         SkIntToScalar(2));
     49         }
     50         {
     51             SkPath* thinHyperbola = &fPaths.push_back();
     52             thinHyperbola->moveTo(0, -0);
     53             thinHyperbola->conicTo(SkIntToScalar(100), SkIntToScalar(100),
     54                                         SkIntToScalar(5), SkIntToScalar(0),
     55                                         SkIntToScalar(2));
     56         }
     57         {
     58             SkPath* veryThinHyperbola = &fPaths.push_back();
     59             veryThinHyperbola->moveTo(0, -0);
     60             veryThinHyperbola->conicTo(SkIntToScalar(100), SkIntToScalar(100),
     61                                         SkIntToScalar(1), SkIntToScalar(0),
     62                                         SkIntToScalar(2));
     63         }
     64         {
     65             SkPath* closedHyperbola = &fPaths.push_back();
     66             closedHyperbola->moveTo(0, -0);
     67             closedHyperbola->conicTo(SkIntToScalar(100), SkIntToScalar(100),
     68                                         SkIntToScalar(0), SkIntToScalar(0),
     69                                         SkIntToScalar(2));
     70         }
     71         {
     72             // using 1 as weight defaults to using quadTo
     73             SkPath* nearParabola = &fPaths.push_back();
     74             nearParabola->moveTo(0, -0);
     75             nearParabola->conicTo(SkIntToScalar(0), SkIntToScalar(100),
     76                                         SkIntToScalar(100), SkIntToScalar(100),
     77                                         0.999f);
     78         }
     79         {
     80             SkPath* thinEllipse = &fPaths.push_back();
     81             thinEllipse->moveTo(0, -0);
     82             thinEllipse->conicTo(SkIntToScalar(100), SkIntToScalar(100),
     83                                         SkIntToScalar(5), SkIntToScalar(0),
     84                                         SK_ScalarHalf);
     85         }
     86         {
     87             SkPath* veryThinEllipse = &fPaths.push_back();
     88             veryThinEllipse->moveTo(0, -0);
     89             veryThinEllipse->conicTo(SkIntToScalar(100), SkIntToScalar(100),
     90                                         SkIntToScalar(1), SkIntToScalar(0),
     91                                         SK_ScalarHalf);
     92         }
     93         {
     94             SkPath* closedEllipse = &fPaths.push_back();
     95             closedEllipse->moveTo(0, -0);
     96             closedEllipse->conicTo(SkIntToScalar(100), SkIntToScalar(100),
     97                                         SkIntToScalar(0), SkIntToScalar(0),
     98                                         SK_ScalarHalf);
     99         }
    100     }
    101 
    102     virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
    103         static const SkAlpha kAlphaValue[] = { 0xFF, 0x40 };
    104 
    105         enum {
    106             kMargin = 15,
    107         };
    108         int wrapX = canvas->getDeviceSize().fWidth - kMargin;
    109 
    110         SkScalar maxH = 0;
    111         canvas->translate(SkIntToScalar(kMargin), SkIntToScalar(kMargin));
    112         canvas->save();
    113 
    114         SkScalar x = SkIntToScalar(kMargin);
    115         for (int p = 0; p < fPaths.count(); ++p) {
    116             for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) {
    117                 for (int aa = 0; aa < 2; ++aa) {
    118                     for (int fh = 0; fh < 2; ++fh) {
    119 
    120                         const SkRect& bounds = fPaths[p].getBounds();
    121 
    122                         if (x + bounds.width() > wrapX) {
    123                             canvas->restore();
    124                             canvas->translate(0, maxH + SkIntToScalar(kMargin));
    125                             canvas->save();
    126                             maxH = 0;
    127                             x = SkIntToScalar(kMargin);
    128                         }
    129 
    130                         SkPaint paint;
    131                         paint.setARGB(kAlphaValue[a], 0, 0, 0);
    132                         paint.setAntiAlias(SkToBool(aa));
    133                         if (fh == 1) {
    134                             paint.setStyle(SkPaint::kStroke_Style);
    135                             paint.setStrokeWidth(0);
    136                         } else if (fh == 0) {
    137                             paint.setStyle(SkPaint::kFill_Style);
    138                         }
    139                         canvas->save();
    140                         canvas->translate(-bounds.fLeft, -bounds.fTop);
    141                         canvas->drawPath(fPaths[p], paint);
    142                         canvas->restore();
    143 
    144                         maxH = SkMaxScalar(maxH, bounds.height());
    145 
    146                         SkScalar dx = bounds.width() + SkIntToScalar(kMargin);
    147                         x += dx;
    148                         canvas->translate(dx, 0);
    149                     }
    150                 }
    151             }
    152         }
    153         canvas->restore();
    154     }
    155 
    156     virtual uint32_t onGetFlags() const SK_OVERRIDE {
    157         return  kSkipPDF_Flag;
    158     }
    159 
    160 private:
    161     SkTArray<SkPath> fPaths;
    162     typedef GM INHERITED;
    163 };
    164 
    165 //////////////////////////////////////////////////////////////////////////////
    166 
    167 DEF_GM( return SkNEW(ConicPathsGM); )
    168 }
    169