--- a/include/SDL_rect.h Tue Dec 23 01:28:06 2008 +0000
+++ b/include/SDL_rect.h Tue Dec 23 02:23:18 2008 +0000
@@ -104,6 +104,18 @@
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* */
--- a/src/video/SDL_blendline.c Tue Dec 23 01:28:06 2008 +0000
+++ b/src/video/SDL_blendline.c Tue Dec 23 02:23:18 2008 +0000
@@ -204,11 +204,10 @@
}
/* 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)) {
--- a/src/video/SDL_drawline.c Tue Dec 23 01:28:06 2008 +0000
+++ b/src/video/SDL_drawline.c Tue Dec 23 02:23:18 2008 +0000
@@ -34,11 +34,9 @@
}
/* 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:
--- a/src/video/SDL_rect.c Tue Dec 23 01:28:06 2008 +0000
+++ b/src/video/SDL_rect.c Tue Dec 23 02:23:18 2008 +0000
@@ -118,6 +118,75 @@
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)
{
--- a/src/video/SDL_video.c Tue Dec 23 01:28:06 2008 +0000
+++ b/src/video/SDL_video.c Tue Dec 23 02:23:18 2008 +0000
@@ -2119,19 +2119,15 @@
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);
}