#include typedef int outcode_t; #define NONE 0 #define Top 1 #define Bottom 2 #define Left 8 #define Right 4 static outcode_t CompOutCode(AWindow * w, int x, int y) { outcode_t code = NONE; if (y > w->clip.y2) { code |= Top; } else if (y < w->clip.y1) { code |= Bottom; } if (x > w->clip.x2) { code |= Right; } else if (x < w->clip.x1) { code |= Left; } return code; } /* * Cohen/Sutherland 2D clipping alorithm as described by Foley, van Dam, * Feiner and Hughes */ int ClipLine(AWindow * w, int *x0, int *y0, int *x1, int *y1) { outcode_t outcode0, outcode1, outcodeOut; int accept = 1, done = 0; outcode0 = CompOutCode(w, *x0, *y0); outcode1 = CompOutCode(w, *x1, *y1); do { if (outcode0 == 0 && outcode1 == 0) { accept = 0; done = 1; } else if (outcode0 & outcode1) { done = 1; } else { int x, y; outcodeOut = outcode0 ? outcode0 : outcode1; if (outcodeOut & Top) { x = *x0 + (*x1 - *x0) * (w->clip.y2 - *y0) / (*y1 - *y0); y = w->clip.y2; } else if (outcodeOut & Bottom) { x = *x0 + (*x1 - *x0) * (w->clip.y1 - *y0) / (*y1 - *y0); y = w->clip.y1; } else if (outcodeOut & Right) { y = *y0 + (*y1 - *y0) * (w->clip.x2 - *x0) / (*x1 - *x0); x = w->clip.x2; } else { /* Left */ y = *y0 + (*y1 - *y0) * (w->clip.x1 - *x0) / (*x1 - *x0); x = w->clip.x1; } if (outcodeOut == outcode0) { *x0 = x; *y0 = y; outcode0 = CompOutCode(w, *x0, *y0); } else { *x1 = x; *y1 = y; outcode1 = CompOutCode(w, *x1, *y1); } } } while (done == 0); return accept; }