Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Added line clipping

  • Loading branch information
slouken committed Dec 23, 2008
1 parent c93a087 commit 4f8e2f5a2003b5b29ca8e284be7745baca3f6a90
Showing with 91 additions and 17 deletions.
  1. +12 −0 include/SDL_rect.h
  2. +4 −5 src/video/SDL_blendline.c
  3. +3 −5 src/video/SDL_drawline.c
  4. +69 −0 src/video/SDL_rect.c
  5. +3 −7 src/video/SDL_video.c
@@ -104,6 +104,18 @@ extern DECLSPEC void SDLCALL SDL_UnionRect(const SDL_Rect * A,
const SDL_Rect * B,
SDL_Rect * result);

/**
* \fn SDL_bool SDL_IntersectRectAndLine(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2)
*
* \brief Calculate the intersection of a rectangle and line segment.
*
* \return SDL_TRUE if there is an intersection, SDL_FALSE otherwise.
*/
extern DECLSPEC SDL_bool SDLCALL SDL_IntersectRectAndLine(const SDL_Rect *
rect, int *X1,
int *Y1, int *X2,
int *Y2);

/* Ends C function definitions when using C++ */
#ifdef __cplusplus
/* *INDENT-OFF* */
@@ -204,11 +204,10 @@ SDL_BlendLine(SDL_Surface * dst, int x1, int y1, int x2, int y2,
}

/* Perform clipping */
/* FIXME
if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
return (0);
}
*/
if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &x2, &y1, &y2)) {
return (0);
}


if ((blendMode == SDL_BLENDMODE_BLEND)
|| (blendMode == SDL_BLENDMODE_ADD)) {
@@ -34,11 +34,9 @@ SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
}

/* Perform clipping */
/* FIXME
if (!SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect)) {
return (0);
}
*/
if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &x2, &y1, &y2)) {
return (0);
}

switch (dst->format->BytesPerPixel) {
case 1:
@@ -118,6 +118,75 @@ SDL_UnionRect(const SDL_Rect * A, const SDL_Rect * B, SDL_Rect * result)
result->h = Amax - Amin;
}

SDL_bool
SDL_IntersectRectAndLine(const SDL_Rect *rect, int *X1, int *Y1, int *X2, int *Y2)
{
int x1, y1;
int x2, y2;
int rectx1;
int recty1;
int rectx2;
int recty2;

if (!rect || !X1 || !Y1 || !X2 || !Y2) {
SDL_FALSE;
}

x1 = *X1;
y1 = *Y1;
x2 = *X2;
y2 = *Y2;
rectx1 = rect->x;
recty1 = rect->y;
rectx2 = rect->x + rect->w - 1;
recty2 = rect->y + rect->h - 1;

/* Check to see if entire line is inside rect */
if (x1 >= rectx1 && x1 <= rectx2 && x2 >= rectx1 && x2 <= rectx2 &&
y1 >= recty1 && y1 <= recty2 && y2 >= recty1 && y2 <= recty2) {
return SDL_TRUE;
}

/* Check to see if entire line is outside rect */
if ((x1 < rectx1 && x2 < rectx1) || (x1 > rectx2 && x2 > rectx2) ||
(y1 < recty1 && y2 < recty2) || (y1 > recty2 && y2 > recty2)) {
return SDL_FALSE;
}

if (y1 = y2) {
/* Horizontal line, easy to clip */
if (x1 < rectx1) {
*X1 = rectx1;
} else if (x1 > rectx2) {
*X1 = rectx2;
}
if (x2 < rectx1) {
*X2 = rectx1;
} else if (x2 > rectx2) {
*X2 = rectx2;
}
return SDL_TRUE;
}

if (x1 == x2) {
/* Vertical line, easy to clip */
if (y1 < recty1) {
*Y1 = recty1;
} else if (y1 > recty2) {
*Y1 = recty2;
}
if (y2 < recty1) {
*Y2 = recty1;
} else if (y2 > recty2) {
*Y2 = recty2;
}
return SDL_TRUE;
}

/* FIXME: need code to clip diagonal line to rect */
return SDL_FALSE;
}

void
SDL_AddDirtyRect(SDL_DirtyRectList * list, const SDL_Rect * rect)
{
@@ -2119,19 +2119,15 @@ SDL_RenderLine(int x1, int y1, int x2, int y2)
SDL_Unsupported();
return -1;
}
#if 0
//FIXME: Need line intersect routine
window = SDL_GetWindowFromID(renderer->window);

real_rect.x = 0;
real_rect.y = 0;
real_rect.w = window->w;
real_rect.h = window->h;
if (rect) {
if (!SDL_IntersectRect(rect, &real_rect, &real_rect)) {
return 0;
}
if (!SDL_IntersectRectAndLine(&real_rect, &x1, &x2, &y1, &y2)) {
return (0);
}
#endif
return renderer->RenderLine(renderer, x1, y1, x2, y2);
}

0 comments on commit 4f8e2f5

Please sign in to comment.