Mercurial > sdl-ios-xcode
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: */ |