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