Mercurial > sdl-ios-xcode
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) |