Mercurial > hg > dmlib
changeset 262:9d015d32841a
Clean up the line clipping a bit, in preparation for fixes.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Wed, 10 Oct 2012 12:11:20 +0300 |
parents | eb77496ab7b3 |
children | ddb24754a67c |
files | dmlib.h dmline.c dmlineclip.h |
diffstat | 3 files changed, 60 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/dmlib.h Wed Oct 10 01:03:15 2012 +0300 +++ b/dmlib.h Wed Oct 10 12:11:20 2012 +0300 @@ -273,6 +273,14 @@ #define DM_HEADER #include "dmlinefunc.h" +enum +{ + CLIP_TOP = 1, + CLIP_BOTTOM = 2, + CLIP_RIGHT = 4, + CLIP_LEFT = 8 +}; + #define DM_CLIP_FUNC dmClipLineCoordsInt #define DM_COORD_TYPE int #include "dmlineclip.h"
--- a/dmline.c Wed Oct 10 01:03:15 2012 +0300 +++ b/dmline.c Wed Oct 10 12:11:20 2012 +0300 @@ -11,22 +11,6 @@ * > 0 : Clipped. Line partially inside the clipping area. * < 0 : Line completely outside the clipping area. */ -#define dmClipBits(Q, x, y) \ - do { \ - Q = 0; \ - if (x < clipX0) Q |= 1; \ - else \ - if (x > clipX1) Q |= 2; \ - if (y < clipY0) Q |= 4; \ - else \ - if (y > clipY1) Q |= 8; \ - } while (0) - -#define xA (*x0) -#define xB (*x1) -#define yA (*y0) -#define yB (*y1) - #define DM_CLIP_FUNC dmClipLineCoordsInt #define DM_COORD_TYPE int #include "dmlineclip.h"
--- a/dmlineclip.h Wed Oct 10 01:03:15 2012 +0300 +++ b/dmlineclip.h Wed Oct 10 12:11:20 2012 +0300 @@ -1,3 +1,21 @@ +#ifndef DM_HEADER +#define DM_CLIP_BITS(Q, x, y) \ + do { \ + Q = 0; \ + if (x < clipX0) Q |= CLIP_TOP; \ + else \ + if (x > clipX1) Q |= CLIP_BOTTOM; \ + if (y < clipY0) Q |= CLIP_RIGHT; \ + else \ + if (y > clipY1) Q |= CLIP_LEFT; \ + } while (0) + +#define xA (*x0) +#define xB (*x1) +#define yA (*y0) +#define yB (*y1) +#endif + int DM_CLIP_FUNC (SDL_Surface *screen, DM_COORD_TYPE *x0, DM_COORD_TYPE *y0, DM_COORD_TYPE *x1, DM_COORD_TYPE *y1) #ifdef DM_HEADER @@ -10,62 +28,64 @@ clipX1 = clipX0 + screen->clip_rect.w - 1, clipY1 = clipY0 + screen->clip_rect.h - 1; - int cA, cB; + int clipA, clipB; - dmClipBits(cA, xA, yA); - dmClipBits(cB, xB, yB); + DM_CLIP_BITS(clipA, xA, yA); + DM_CLIP_BITS(clipB, xB, yB); - if (cA & cB) - return -1; /* the line segment is outside */ + // The line segment is outside of the clip region + if (clipA & clipB) + return -1; - if ((cA | cB) == 0) /* the line segment is inside of the clipping rectangle */ + // The segment is inside? + if ((clipA | clipB) == 0) return 0; #if 1 // Cohen-Sutherland clipping method do { - const int c = cA ? cA : cB; + const int c = clipA ? clipA : clipB; DM_COORD_TYPE x, y; - if (c & 1) + if (c & CLIP_TOP) { - y = yA + ((clipX0 - xA)*(yB - yA)) / (xB - xA); + y = yA + ((clipX0 + xA) * (yB - yA)) / xB - xA; x = clipX0; } else - if (c & 2) + if (c & CLIP_BOTTOM) { y = yA + ((clipX1 - xA)*(yB - yA)) / (xB - xA); x = clipX1; } else - if (c & 4) + if (c & CLIP_RIGHT) { x = xA + ((clipY0 - yA)*(xB - xA)) / (yB - yA); y = clipY0; } else - if (c & 8) + if (c & CLIP_LEFT) { x = xA + ((clipY1 - yA)*(xB - xA)) / (yB - yA); y = clipY1; } - if (c == cA) + if (c == clipA) { xA = x; yA = y; - dmClipBits(cA, xA, yA); + DM_CLIP_BITS(clipA, xA, yA); } else { xB = x; yB = y; - dmClipBits(cB, xB, yB); + DM_CLIP_BITS(clipB, xB, yB); } - } while (cA | cB); + } while (clipA | clipB); #else // Buyu-Skala clipping method const DM_COORD_TYPE dx = xB - xA; @@ -73,10 +93,10 @@ float k, m; int z; - switch (cA + cB) + switch (clipA + clipB) { case 1: - if (cA == 1) + if (clipA == 1) { xA = clipX0; yA = (clipX0 - xB) * dy / dx + yB; @@ -101,7 +121,7 @@ z = (clipX0 - xA) * k + yA; if (z < clipY0) { - switch (cA) + switch (clipA) { case 0: xB = xB + (clipY0 - yB) / k; @@ -118,7 +138,7 @@ } else { - switch (cA) + switch (clipA) { case 0: xB = clipX0; @@ -145,7 +165,7 @@ break; case 7: - switch (cA) + switch (clipA) { case 1: k = dy / dx; @@ -163,10 +183,10 @@ xB = clipX1; break; - /* similarly for cases cA == 2, 5, 6 */ + /* similarly for cases clipA == 2, 5, 6 */ } case 15: - switch (cA) + switch (clipA) { case 5: if (dy * (clipX1 - clipX0) < dx * (clipY1 - clipY0)) @@ -224,16 +244,23 @@ } } - /* similarly for cases cA == 6, 9, 10 */ + /* similarly for cases clipA == 6, 9, 10 */ } /* cases 2, 4, 8 are similar as case 1, cases 6, 9, 10 are similar as case 5 */ /* cases 11, 13, 14 are similar as case 7, case 12 is similar case 3 */ - } /* of case cA + cB */ + } /* of case clipA + clipB */ #endif return 1; } + +#undef DM_CLIP_BITS +#undef xA +#undef xB +#undef yA +#undef yB + #endif #undef DM_CLIP_FUNC