comparison src/video/SDL_drawline.c @ 3596:f638ded38b8a

Added SDL_RenderClear() as a fast method of clearing the screen to the drawing color. Renamed SDL_RenderPoint() and SDL_RenderLine() to SDL_RenderDrawPoint() and SDL_RenderDrawLine(). Added API for rectangle drawing (as opposed to filling) Added placeholder API functions for circles and ellipses ... I'm not sure whether these will stay. Optimized software line drawing quite a bit. Added support for Wu's anti-aliased line drawing, currently disabled by default.
author Sam Lantinga <slouken@libsdl.org>
date Wed, 23 Dec 2009 01:55:00 +0000
parents c8bed77b0386
children 0d6f520c0eb9
comparison
equal deleted inserted replaced
3595:b7c6828d4039 3596:f638ded38b8a
21 */ 21 */
22 #include "SDL_config.h" 22 #include "SDL_config.h"
23 23
24 #include "SDL_draw.h" 24 #include "SDL_draw.h"
25 25
26 static void
27 SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
28 SDL_bool draw_end)
29 {
30 if (y1 == y2) {
31 HLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
32 } else if (x1 == x2) {
33 VLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
34 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
35 DLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
36 } else {
37 BLINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY1, draw_end);
38 }
39 }
40
41 static void
42 SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
43 SDL_bool draw_end)
44 {
45 if (y1 == y2) {
46 HLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
47 } else if (x1 == x2) {
48 VLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
49 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
50 DLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
51 } else {
52 Uint8 _r, _g, _b, _a;
53 const SDL_PixelFormat * fmt = dst->format;
54 SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
55 if (fmt->Rmask == 0x7C00) {
56 AALINE(x1, y1, x2, y2,
57 DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB555,
58 draw_end);
59 } else if (fmt->Rmask == 0xF800) {
60 AALINE(x1, y1, x2, y2,
61 DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB565,
62 draw_end);
63 } else {
64 AALINE(x1, y1, x2, y2,
65 DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY2_BLEND_RGB,
66 draw_end);
67 }
68 }
69 }
70
71 static void
72 SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
73 SDL_bool draw_end)
74 {
75 if (y1 == y2) {
76 HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
77 } else if (x1 == x2) {
78 VLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
79 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
80 DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
81 } else {
82 Uint8 _r, _g, _b, _a;
83 const SDL_PixelFormat * fmt = dst->format;
84 SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
85 if (fmt->Rmask == 0x00FF0000) {
86 if (!fmt->Amask) {
87 AALINE(x1, y1, x2, y2,
88 DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888,
89 draw_end);
90 } else {
91 AALINE(x1, y1, x2, y2,
92 DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888,
93 draw_end);
94 }
95 } else {
96 AALINE(x1, y1, x2, y2,
97 DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY4_BLEND_RGB,
98 draw_end);
99 }
100 }
101 }
102
103 typedef void (*DrawLineFunc) (SDL_Surface * dst,
104 int x1, int y1, int x2, int y2,
105 Uint32 color, SDL_bool draw_end);
106
107 static DrawLineFunc
108 SDL_CalculateDrawLineFunc(const SDL_PixelFormat * fmt)
109 {
110 switch (fmt->BytesPerPixel) {
111 case 1:
112 if (fmt->BitsPerPixel < 8) {
113 break;
114 }
115 return SDL_DrawLine1;
116 case 2:
117 return SDL_DrawLine2;
118 case 4:
119 return SDL_DrawLine4;
120 }
121 return NULL;
122 }
26 123
27 int 124 int
28 SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color) 125 SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
29 { 126 {
127 DrawLineFunc func;
128
30 if (!dst) { 129 if (!dst) {
31 SDL_SetError("Passed NULL destination surface"); 130 SDL_SetError("SDL_DrawLine(): Passed NULL destination surface");
32 return -1; 131 return -1;
33 } 132 }
34 133
35 /* This function doesn't work on surfaces < 8 bpp */ 134 func = SDL_CalculateDrawLineFunc(dst->format);
36 if (dst->format->BitsPerPixel < 8) { 135 if (!func) {
37 SDL_SetError("SDL_DrawLine(): Unsupported surface format"); 136 SDL_SetError("SDL_DrawLine(): Unsupported surface format");
38 return -1; 137 return -1;
39 } 138 }
40 139
41 /* Perform clipping */ 140 /* Perform clipping */
42 /* FIXME: We don't actually want to clip, as it may change line slope */ 141 /* FIXME: We don't actually want to clip, as it may change line slope */
43 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { 142 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
44 return (0); 143 return 0;
45 } 144 }
46 145
47 switch (dst->format->BytesPerPixel) { 146 func(dst, x1, y1, x2, y2, color, SDL_TRUE);
48 case 1:
49 DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL1, SDL_TRUE);
50 break;
51 case 2:
52 DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL2, SDL_TRUE);
53 break;
54 case 3:
55 SDL_Unsupported();
56 return -1;
57 case 4:
58 DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL4, SDL_TRUE);
59 break;
60 }
61 return 0; 147 return 0;
62 } 148 }
63 149
64 int 150 int
65 SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count, 151 SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
66 Uint32 color) 152 Uint32 color)
67 { 153 {
68 int i; 154 int i;
155 int x1, y1;
156 int x2, y2;
157 SDL_bool draw_end;
158 DrawLineFunc func;
69 159
70 if (!dst) { 160 if (!dst) {
71 SDL_SetError("Passed NULL destination surface"); 161 SDL_SetError("SDL_DrawLines(): Passed NULL destination surface");
72 return -1; 162 return -1;
73 } 163 }
74 164
75 /* This function doesn't work on surfaces < 8 bpp */ 165 func = SDL_CalculateDrawLineFunc(dst->format);
76 if (dst->format->BitsPerPixel < 8) { 166 if (!func) {
77 SDL_SetError("SDL_DrawLine(): Unsupported surface format"); 167 SDL_SetError("SDL_DrawLines(): Unsupported surface format");
78 return -1; 168 return -1;
79 } 169 }
80 170
81 if (count < 2) {
82 return 0;
83 }
84
85 for (i = 1; i < count; ++i) { 171 for (i = 1; i < count; ++i) {
86 int x1 = points[i-1].x; 172 x1 = points[i-1].x;
87 int y1 = points[i-1].y; 173 y1 = points[i-1].y;
88 int x2 = points[i].x; 174 x2 = points[i].x;
89 int y2 = points[i].y; 175 y2 = points[i].y;
90 176
91 /* Perform clipping */ 177 /* Perform clipping */
92 /* FIXME: We don't actually want to clip, as it may change line slope */ 178 /* FIXME: We don't actually want to clip, as it may change line slope */
93 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) { 179 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
94 continue; 180 continue;
95 } 181 }
96 182
97 switch (dst->format->BytesPerPixel) { 183 /* Draw the end if it was clipped */
98 case 1: 184 draw_end = (x2 != points[i].x || y2 != points[i].y);
99 DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL1, SDL_TRUE); 185
100 break; 186 func(dst, x1, y1, x2, y2, color, draw_end);
101 case 2: 187 }
102 DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL2, SDL_TRUE); 188 if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
103 break; 189 SDL_DrawPoint(dst, points[count-1].x, points[count-1].y, color);
104 case 3:
105 SDL_Unsupported();
106 return -1;
107 case 4:
108 DRAWLINE(x1, y1, x2, y2, DRAW_FASTSETPIXEL4, SDL_TRUE);
109 break;
110 }
111 } 190 }
112 return 0; 191 return 0;
113 } 192 }
114 193
115 /* vi: set ts=4 sw=4 expandtab: */ 194 /* vi: set ts=4 sw=4 expandtab: */