Home | History | Annotate | Download | only in samplecode
      1 #include "SampleCode.h"
      2 #include "SkView.h"
      3 #include "SkCanvas.h"
      4 #include "SkGradientShader.h"
      5 #include "SkGraphics.h"
      6 #include "SkImageDecoder.h"
      7 #include "SkPath.h"
      8 #include "SkRegion.h"
      9 #include "SkShader.h"
     10 #include "SkUtils.h"
     11 #include "SkXfermode.h"
     12 #include "SkColorPriv.h"
     13 #include "SkColorFilter.h"
     14 #include "SkTime.h"
     15 #include "SkRandom.h"
     16 
     17 #include "SkLineClipper.h"
     18 #include "SkEdgeClipper.h"
     19 
     20 #define AUTO_ANIMATE    true
     21 
     22 static int test0(SkPoint pts[], SkRect* clip) {
     23     pts[0].set(200000, 140);
     24     pts[1].set(-740000, 483);
     25     pts[2].set(1.00000102e-06f, 9.10000017e-05f);
     26     clip->set(0, 0, 640, 480);
     27     return 2;
     28 }
     29 
     30 ///////////////////////////////////////////////////////////////////////////////
     31 
     32 static void drawQuad(SkCanvas* canvas, const SkPoint pts[3], const SkPaint& p) {
     33     SkPath path;
     34     path.moveTo(pts[0]);
     35     path.quadTo(pts[1], pts[2]);
     36     canvas->drawPath(path, p);
     37 }
     38 
     39 static void drawCubic(SkCanvas* canvas, const SkPoint pts[4], const SkPaint& p) {
     40     SkPath path;
     41     path.moveTo(pts[0]);
     42     path.cubicTo(pts[1], pts[2], pts[3]);
     43     canvas->drawPath(path, p);
     44 }
     45 
     46 typedef void (*clipper_proc)(const SkPoint src[], const SkRect& clip,
     47                             SkCanvas*, const SkPaint&, const SkPaint&);
     48 
     49 static void check_clipper(int count, const SkPoint pts[], const SkRect& clip) {
     50     for (int i = 0; i < count; i++) {
     51         SkASSERT(pts[i].fX >= clip.fLeft);
     52         SkASSERT(pts[i].fX <= clip.fRight);
     53         SkASSERT(pts[i].fY >= clip.fTop);
     54         SkASSERT(pts[i].fY <= clip.fBottom);
     55     }
     56 
     57     if (count > 1) {
     58         sk_assert_monotonic_y(pts, count);
     59     }
     60 }
     61 
     62 static void line_intersector(const SkPoint src[], const SkRect& clip,
     63                          SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
     64     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
     65 
     66     SkPoint dst[2];
     67     if (SkLineClipper::IntersectLine(src, clip, dst)) {
     68         check_clipper(2, dst, clip);
     69         canvas->drawPoints(SkCanvas::kLines_PointMode, 2, dst, p0);
     70     }
     71 }
     72 
     73 static void line_clipper(const SkPoint src[], const SkRect& clip,
     74                          SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
     75     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
     76 
     77     SkPoint dst[SkLineClipper::kMaxPoints];
     78     int count = SkLineClipper::ClipLine(src, clip, dst);
     79     for (int i = 0; i < count; i++) {
     80         check_clipper(2, &dst[i], clip);
     81         canvas->drawPoints(SkCanvas::kLines_PointMode, 2, &dst[i], p0);
     82     }
     83 }
     84 
     85 static void quad_clipper(const SkPoint src[], const SkRect& clip,
     86                          SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
     87     drawQuad(canvas, src, p1);
     88 
     89     SkEdgeClipper clipper;
     90     if (clipper.clipQuad(src, clip)) {
     91         SkPoint pts[4];
     92         SkPath::Verb verb;
     93         while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
     94             switch (verb) {
     95                 case SkPath::kLine_Verb:
     96                     check_clipper(2, pts, clip);
     97                     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
     98                     break;
     99                 case SkPath::kQuad_Verb:
    100                     check_clipper(3, pts, clip);
    101                     drawQuad(canvas, pts, p0);
    102                     break;
    103                 default:
    104                     SkASSERT(!"unexpected verb");
    105             }
    106         }
    107     }
    108 }
    109 
    110 static void cubic_clipper(const SkPoint src[], const SkRect& clip,
    111                        SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
    112     drawCubic(canvas, src, p1);
    113 
    114     SkEdgeClipper clipper;
    115     if (clipper.clipCubic(src, clip)) {
    116         SkPoint pts[4];
    117         SkPath::Verb verb;
    118         while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
    119             switch (verb) {
    120                 case SkPath::kLine_Verb:
    121                     check_clipper(2, pts, clip);
    122                     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
    123                     break;
    124                 case SkPath::kCubic_Verb:
    125                  //   check_clipper(4, pts, clip);
    126                     drawCubic(canvas, pts, p0);
    127                     break;
    128                 default:
    129                     SkASSERT(!"unexpected verb");
    130             }
    131         }
    132     }
    133 }
    134 
    135 static const clipper_proc gProcs[] = {
    136     line_intersector,
    137     line_clipper,
    138     quad_clipper,
    139     cubic_clipper
    140 };
    141 
    142 ///////////////////////////////////////////////////////////////////////////////
    143 
    144 enum {
    145     W = 640/3,
    146     H = 480/3
    147 };
    148 
    149 class LineClipperView : public SkView {
    150     SkMSec      fNow;
    151     int         fCounter;
    152     int         fProcIndex;
    153     SkRect      fClip;
    154     SkRandom    fRand;
    155     SkPoint     fPts[4];
    156 
    157     void randPts() {
    158         for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
    159             fPts[i].set(fRand.nextUScalar1() * 640,
    160                         fRand.nextUScalar1() * 480);
    161         }
    162         fCounter += 1;
    163     }
    164 
    165 public:
    166 	LineClipperView() {
    167         fProcIndex = 0;
    168         fCounter = 0;
    169         fNow = 0;
    170 
    171         int x = (640 - W)/2;
    172         int y = (480 - H)/2;
    173         fClip.set(SkIntToScalar(x), SkIntToScalar(y),
    174                   SkIntToScalar(x + W), SkIntToScalar(y + H));
    175         this->randPts();
    176     }
    177 
    178 protected:
    179     // overrides from SkEventSink
    180     virtual bool onQuery(SkEvent* evt) {
    181         if (SampleCode::TitleQ(*evt)) {
    182             SampleCode::TitleR(evt, "LineClipper");
    183             return true;
    184         }
    185         return this->INHERITED::onQuery(evt);
    186     }
    187 
    188     void drawBG(SkCanvas* canvas) {
    189         canvas->drawColor(SK_ColorWHITE);
    190     }
    191 
    192     static void drawVLine(SkCanvas* canvas, SkScalar x, const SkPaint& paint) {
    193         canvas->drawLine(x, -999, x, 999, paint);
    194     }
    195 
    196     static void drawHLine(SkCanvas* canvas, SkScalar y, const SkPaint& paint) {
    197         canvas->drawLine(-999, y, 999, y, paint);
    198     }
    199 
    200     virtual void onDraw(SkCanvas* canvas) {
    201         this->drawBG(canvas);
    202 
    203         SkMSec now = SampleCode::GetAnimTime();
    204         if (fNow != now) {
    205             fNow = now;
    206             this->randPts();
    207             this->inval(NULL);
    208         }
    209 
    210      //   fProcIndex = test0(fPts, &fClip);
    211 
    212         SkPaint paint, paint1;
    213 
    214         drawVLine(canvas, fClip.fLeft + SK_ScalarHalf, paint);
    215         drawVLine(canvas, fClip.fRight - SK_ScalarHalf, paint);
    216         drawHLine(canvas, fClip.fTop + SK_ScalarHalf, paint);
    217         drawHLine(canvas, fClip.fBottom - SK_ScalarHalf, paint);
    218 
    219         paint.setColor(SK_ColorLTGRAY);
    220         canvas->drawRect(fClip, paint);
    221 
    222         paint.setAntiAlias(true);
    223         paint.setColor(SK_ColorBLUE);
    224         paint.setStyle(SkPaint::kStroke_Style);
    225       //  paint.setStrokeWidth(SkIntToScalar(3));
    226         paint.setStrokeCap(SkPaint::kRound_Cap);
    227 
    228         paint1.setAntiAlias(true);
    229         paint1.setColor(SK_ColorRED);
    230         paint1.setStyle(SkPaint::kStroke_Style);
    231         gProcs[fProcIndex](fPts, fClip, canvas, paint, paint1);
    232     }
    233 
    234     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
    235      //   fProcIndex = (fProcIndex + 1) % SK_ARRAY_COUNT(gProcs);
    236         if (x < 50 && y < 50) {
    237             this->randPts();
    238         }
    239         this->inval(NULL);
    240         return NULL;
    241     }
    242 
    243     virtual bool onClick(Click* click) {
    244         return false;
    245     }
    246 
    247 private:
    248     typedef SkView INHERITED;
    249 };
    250 
    251 //////////////////////////////////////////////////////////////////////////////
    252 
    253 static SkView* MyFactory() { return new LineClipperView; }
    254 static SkViewRegister reg(MyFactory);
    255 
    256