comparison src/video/x11/SDL_x11render.c @ 3543:c2154674c0c1

Fixed X11 line implementation - clip lines that are going to go outside the window.
author Sam Lantinga <slouken@libsdl.org>
date Fri, 11 Dec 2009 09:59:36 +0000
parents a1896642a47e
children 5f26a7eb5ff0
comparison
equal deleted inserted replaced
3542:97eae5a705f9 3543:c2154674c0c1
20 slouken@libsdl.org 20 slouken@libsdl.org
21 */ 21 */
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 #if SDL_VIDEO_RENDER_X11 24 #if SDL_VIDEO_RENDER_X11
25
26 #include <limits.h> /* For INT_MIN and INT_MAX */
25 27
26 #include "SDL_x11video.h" 28 #include "SDL_x11video.h"
27 #include "../SDL_rect_c.h" 29 #include "../SDL_rect_c.h"
28 #include "../SDL_pixels_c.h" 30 #include "../SDL_pixels_c.h"
29 #include "../SDL_yuv_sw_c.h" 31 #include "../SDL_yuv_sw_c.h"
645 { 647 {
646 X11_RenderData *data = (X11_RenderData *) renderer->driverdata; 648 X11_RenderData *data = (X11_RenderData *) renderer->driverdata;
647 SDL_Window *window = SDL_GetWindowFromID(renderer->window); 649 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
648 SDL_Rect clip, rect; 650 SDL_Rect clip, rect;
649 unsigned long foreground; 651 unsigned long foreground;
652 XPoint *xpoints, *xpoint;
653 int i, xcount;
654 int minx, miny;
655 int maxx, maxy;
650 656
651 clip.x = 0; 657 clip.x = 0;
652 clip.y = 0; 658 clip.y = 0;
653 clip.w = window->w; 659 clip.w = window->w;
654 clip.h = window->h; 660 clip.h = window->h;
655 661
656 if (data->makedirty) {
657 /* Get the smallest rectangle that contains everything */
658 SDL_EnclosePoints(points, count, NULL, &rect);
659 if (!SDL_IntersectRect(&rect, &clip, &rect)) {
660 /* Nothing to draw */
661 return 0;
662 }
663 SDL_AddDirtyRect(&data->dirty, &rect);
664 }
665
666 foreground = renderdrawcolor(renderer, 1); 662 foreground = renderdrawcolor(renderer, 1);
667 XSetForeground(data->display, data->gc, foreground); 663 XSetForeground(data->display, data->gc, foreground);
668 /* FIXME: Can we properly handle lines that extend beyond visible space? */ 664
669 //XDrawLine(data->display, data->drawable, data->gc, x1, y1, x2, y2); 665 xpoint = xpoints = SDL_stack_alloc(XPoint, count);
666 xcount = 0;
667 minx = INT_MAX;
668 miny = INT_MAX;
669 maxx = INT_MIN;
670 maxy = INT_MIN;
671 for (i = 0; i < count; ++i) {
672 int x = points[i].x;
673 int y = points[i].y;
674
675 /* If the point is inside the window, add it to the list */
676 if (x >= 0 && x < window->w && y >= 0 && y < window->h) {
677 if (x < minx) {
678 minx = x;
679 } else if (x > maxx) {
680 maxx = x;
681 }
682 if (y < miny) {
683 miny = y;
684 } else if (y > maxy) {
685 maxy = y;
686 }
687 xpoint->x = (short)x;
688 xpoint->y = (short)y;
689 ++xpoint;
690 ++xcount;
691 continue;
692 }
693
694 /* We need to clip the line segments joined by this point */
695 if (xcount > 0) {
696 int x1 = xpoint[-1].x;
697 int y1 = xpoint[-1].y;
698 int x2 = x;
699 int y2 = y;
700 if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
701 if (x2 < minx) {
702 minx = x2;
703 } else if (x2 > maxx) {
704 maxx = x2;
705 }
706 if (y2 < miny) {
707 miny = y2;
708 } else if (y2 > maxy) {
709 maxy = y2;
710 }
711 xpoint->x = (short)x2;
712 xpoint->y = (short)y2;
713 ++xpoint;
714 ++xcount;
715 }
716 XDrawLines(data->display, data->drawable, data->gc,
717 xpoints, xcount, CoordModeOrigin);
718 if (xpoints[0].x != x2 || xpoints[0].y != y2) {
719 XDrawPoint(data->display, data->drawable, data->gc, x2, y2);
720 }
721 if (data->makedirty) {
722 SDL_Rect rect;
723
724 rect.x = minx;
725 rect.y = miny;
726 rect.w = (maxx - minx) + 1;
727 rect.h = (maxy - miny) + 1;
728 SDL_AddDirtyRect(&data->dirty, &rect);
729 }
730 xpoint = xpoints;
731 xcount = 0;
732 minx = INT_MAX;
733 miny = INT_MAX;
734 maxx = INT_MIN;
735 maxy = INT_MIN;
736 }
737 if (i < (count-1)) {
738 int x1 = x;
739 int y1 = y;
740 int x2 = points[i+1].x;
741 int y2 = points[i+1].y;
742 if (SDL_IntersectRectAndLine(&clip, &x1, &y1, &x2, &y2)) {
743 if (x1 < minx) {
744 minx = x1;
745 } else if (x1 > maxx) {
746 maxx = x1;
747 }
748 if (y1 < miny) {
749 miny = y1;
750 } else if (y1 > maxy) {
751 maxy = y1;
752 }
753 xpoint->x = (short)x1;
754 xpoint->y = (short)y1;
755 ++xpoint;
756 ++xcount;
757 }
758 }
759 }
760 if (xcount > 1) {
761 int x2 = xpoint[-1].x;
762 int y2 = xpoint[-1].y;
763 XDrawLines(data->display, data->drawable, data->gc, xpoints, xcount,
764 CoordModeOrigin);
765 if (xpoints[0].x != x2 || xpoints[0].y != y2) {
766 XDrawPoint(data->display, data->drawable, data->gc, x2, y2);
767 }
768 if (data->makedirty) {
769 SDL_Rect rect;
770
771 rect.x = minx;
772 rect.y = miny;
773 rect.w = (maxx - minx) + 1;
774 rect.h = (maxy - miny) + 1;
775 SDL_AddDirtyRect(&data->dirty, &rect);
776 }
777 }
778 SDL_stack_free(xpoints);
779
670 return 0; 780 return 0;
671 } 781 }
672 782
673 static int 783 static int
674 X11_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count) 784 X11_RenderRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)