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 "SkPath.h"
     11 #include "SkTArray.h"
     12 
     13 class ConicPathsGM : public skiagm::GM {
     14 protected:
     15 
     16     SkString onShortName() override {
     17         return SkString("conicpaths");
     18     }
     19 
     20     SkISize onISize() override {
     21         return SkISize::Make(920, 960);
     22     }
     23 
     24     void onOnceBeforeDraw() override {
     25         {
     26             const SkScalar w = SkScalarSqrt(2)/2;
     27             SkPath* conicCirlce = &fPaths.push_back();
     28             conicCirlce->moveTo(0, 0);
     29             conicCirlce->conicTo(0, 50, 50, 50, w);
     30             conicCirlce->rConicTo(50, 0, 50, -50, w);
     31             conicCirlce->rConicTo(0, -50, -50, -50, w);
     32             conicCirlce->rConicTo(-50, 0, -50, 50, w);
     33 
     34         }
     35         {
     36             SkPath* hyperbola = &fPaths.push_back();
     37             hyperbola->moveTo(0, 0);
     38             hyperbola->conicTo(0, 100, 100, 100, 2);
     39         }
     40         {
     41             SkPath* thinHyperbola = &fPaths.push_back();
     42             thinHyperbola->moveTo(0, 0);
     43             thinHyperbola->conicTo(100, 100, 5, 0, 2);
     44         }
     45         {
     46             SkPath* veryThinHyperbola = &fPaths.push_back();
     47             veryThinHyperbola->moveTo(0, 0);
     48             veryThinHyperbola->conicTo(100, 100, 1, 0, 2);
     49         }
     50         {
     51             SkPath* closedHyperbola = &fPaths.push_back();
     52             closedHyperbola->moveTo(0, 0);
     53             closedHyperbola->conicTo(100, 100, 0, 0, 2);
     54         }
     55         {
     56             // using 1 as weight defaults to using quadTo
     57             SkPath* nearParabola = &fPaths.push_back();
     58             nearParabola->moveTo(0, 0);
     59             nearParabola->conicTo(0, 100, 100, 100, 0.999f);
     60         }
     61         {
     62             SkPath* thinEllipse = &fPaths.push_back();
     63             thinEllipse->moveTo(0, 0);
     64             thinEllipse->conicTo(100, 100, 5, 0, SK_ScalarHalf);
     65         }
     66         {
     67             SkPath* veryThinEllipse = &fPaths.push_back();
     68             veryThinEllipse->moveTo(0, 0);
     69             veryThinEllipse->conicTo(100, 100, 1, 0, SK_ScalarHalf);
     70         }
     71         {
     72             SkPath* closedEllipse = &fPaths.push_back();
     73             closedEllipse->moveTo(0,  0);
     74             closedEllipse->conicTo(100, 100, 0, 0, SK_ScalarHalf);
     75         }
     76         {
     77             const SkScalar w = SkScalarSqrt(2)/2;
     78             fGiantCircle.moveTo(2.1e+11f, -1.05e+11f);
     79             fGiantCircle.conicTo(2.1e+11f, 0, 1.05e+11f, 0, w);
     80             fGiantCircle.conicTo(0, 0, 0, -1.05e+11f, w);
     81             fGiantCircle.conicTo(0, -2.1e+11f, 1.05e+11f, -2.1e+11f, w);
     82             fGiantCircle.conicTo(2.1e+11f, -2.1e+11f, 2.1e+11f, -1.05e+11f, w);
     83 
     84         }
     85     }
     86 
     87     void drawGiantCircle(SkCanvas* canvas) {
     88         SkPaint paint;
     89         canvas->drawPath(fGiantCircle, paint);
     90     }
     91 
     92     void onDraw(SkCanvas* canvas) override {
     93         const SkAlpha kAlphaValue[] = { 0xFF, 0x40 };
     94 
     95         const SkScalar margin = 15;
     96         canvas->translate(margin, margin);
     97 
     98         SkPaint paint;
     99         for (int p = 0; p < fPaths.count(); ++p) {
    100             canvas->save();
    101             for (size_t a = 0; a < SK_ARRAY_COUNT(kAlphaValue); ++a) {
    102                 paint.setARGB(kAlphaValue[a], 0, 0, 0);
    103                 for (int aa = 0; aa < 2; ++aa) {
    104                     paint.setAntiAlias(SkToBool(aa));
    105                     for (int fh = 0; fh < 2; ++fh) {
    106                         paint.setStyle(fh ? SkPaint::kStroke_Style : SkPaint::kFill_Style);
    107 
    108                         const SkRect& bounds = fPaths[p].getBounds();
    109                         canvas->save();
    110                         canvas->translate(-bounds.fLeft, -bounds.fTop);
    111                         canvas->drawPath(fPaths[p], paint);
    112                         canvas->restore();
    113 
    114                         canvas->translate(110, 0);
    115                     }
    116                 }
    117             }
    118             canvas->restore();
    119             canvas->translate(0, 110);
    120         }
    121         canvas->restore();
    122 
    123         this->drawGiantCircle(canvas);
    124     }
    125 
    126 private:
    127     SkTArray<SkPath> fPaths;
    128     SkPath           fGiantCircle;
    129     typedef skiagm::GM INHERITED;
    130 };
    131 DEF_GM(return new ConicPathsGM;)
    132 
    133 //////////////////////////////////////////////////////////////////////////////
    134 
    135 /* arc should be on top of circle */
    136 DEF_SIMPLE_GM(arccirclegap, canvas, 250, 250) {
    137     canvas->translate(50, 100);
    138     SkPoint c = { 1052.5390625f, 506.8760978034711f };
    139     SkScalar radius = 1096.702150363923f;
    140     SkPaint paint;
    141     paint.setAntiAlias(true);
    142     paint.setStyle(SkPaint::kStroke_Style);
    143     canvas->drawCircle(c, radius, paint);
    144     SkPath path;
    145     path.moveTo(288.88884710654133f, -280.26680862609f);
    146     path.arcTo(0, 0, -39.00216443306411f, 400.6058925796476f, radius);
    147     paint.setColor(0xff007f00);
    148     canvas->drawPath(path, paint);
    149 }
    150 
    151 /* circle should be antialiased */
    152 DEF_SIMPLE_GM(largecircle, canvas, 250, 250) {
    153     canvas->translate(50, 100);
    154     SkPoint c = { 1052.5390625f, 506.8760978034711f };
    155     SkScalar radius = 1096.702150363923f;
    156     SkPaint paint;
    157     paint.setAntiAlias(true);
    158     paint.setStyle(SkPaint::kStroke_Style);
    159     canvas->drawCircle(c, radius, paint);
    160 }
    161 
    162 DEF_SIMPLE_GM(crbug_640176, canvas, 250, 250) {
    163     SkPath path;
    164     path.moveTo(SkBits2Float(0x00000000), SkBits2Float(0x00000000));  // 0, 0
    165     path.lineTo(SkBits2Float(0x42cfd89a), SkBits2Float(0xc2700000));  // 103.923f, -60
    166     path.lineTo(SkBits2Float(0x42cfd899), SkBits2Float(0xc2700006));  // 103.923f, -60
    167     path.conicTo(SkBits2Float(0x42f00000), SkBits2Float(0xc2009d9c),
    168             SkBits2Float(0x42f00001), SkBits2Float(0x00000000),
    169             SkBits2Float(0x3f7746ea));  // 120, -32.1539f, 120, 0, 0.965926f
    170 
    171     SkPaint paint;
    172     paint.setAntiAlias(true);
    173     canvas->translate(125, 125);
    174     canvas->drawPath(path, paint);
    175 }
    176