comparison src/render/software/SDL_drawline.c @ 5166:d72793305335

Making the API simpler, moved the surface drawing functions to the software renderer.
author Sam Lantinga <slouken@libsdl.org>
date Thu, 03 Feb 2011 02:45:29 -0800
parents src/video/SDL_drawline.c@f7b03b6838cb
children 4d39eeaad00b
comparison
equal deleted inserted replaced
5165:e2b3f003e085 5166:d72793305335
1 /*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2010 Sam Lantinga
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19 Sam Lantinga
20 slouken@libsdl.org
21 */
22 #include "SDL_config.h"
23
24 #include "SDL_draw.h"
25 #include "SDL_drawline.h"
26
27
28 static void
29 SDL_DrawLine1(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
30 SDL_bool draw_end)
31 {
32 if (y1 == y2) {
33 //HLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
34 int length;
35 int pitch = (dst->pitch / dst->format->BytesPerPixel);
36 Uint8 *pixel;
37 if (x1 <= x2) {
38 pixel = (Uint8 *)dst->pixels + y1 * pitch + x1;
39 length = draw_end ? (x2-x1+1) : (x2-x1);
40 } else {
41 pixel = (Uint8 *)dst->pixels + y1 * pitch + x2;
42 if (!draw_end) {
43 ++pixel;
44 }
45 length = draw_end ? (x1-x2+1) : (x1-x2);
46 }
47 SDL_memset(pixel, color, length);
48 } else if (x1 == x2) {
49 VLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
50 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
51 DLINE(Uint8, DRAW_FASTSETPIXEL1, draw_end);
52 } else {
53 BLINE(x1, y1, x2, y2, DRAW_FASTSETPIXELXY1, draw_end);
54 }
55 }
56
57 static void
58 SDL_DrawLine2(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
59 SDL_bool draw_end)
60 {
61 if (y1 == y2) {
62 HLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
63 } else if (x1 == x2) {
64 VLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
65 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
66 DLINE(Uint16, DRAW_FASTSETPIXEL2, draw_end);
67 } else {
68 Uint8 _r, _g, _b, _a;
69 const SDL_PixelFormat * fmt = dst->format;
70 SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
71 if (fmt->Rmask == 0x7C00) {
72 AALINE(x1, y1, x2, y2,
73 DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB555,
74 draw_end);
75 } else if (fmt->Rmask == 0xF800) {
76 AALINE(x1, y1, x2, y2,
77 DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY_BLEND_RGB565,
78 draw_end);
79 } else {
80 AALINE(x1, y1, x2, y2,
81 DRAW_FASTSETPIXELXY2, DRAW_SETPIXELXY2_BLEND_RGB,
82 draw_end);
83 }
84 }
85 }
86
87 static void
88 SDL_DrawLine4(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color,
89 SDL_bool draw_end)
90 {
91 if (y1 == y2) {
92 HLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
93 } else if (x1 == x2) {
94 VLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
95 } else if (ABS(x1 - x2) == ABS(y1 - y2)) {
96 DLINE(Uint32, DRAW_FASTSETPIXEL4, draw_end);
97 } else {
98 Uint8 _r, _g, _b, _a;
99 const SDL_PixelFormat * fmt = dst->format;
100 SDL_GetRGBA(color, fmt, &_r, &_g, &_b, &_a);
101 if (fmt->Rmask == 0x00FF0000) {
102 if (!fmt->Amask) {
103 AALINE(x1, y1, x2, y2,
104 DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_RGB888,
105 draw_end);
106 } else {
107 AALINE(x1, y1, x2, y2,
108 DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY_BLEND_ARGB8888,
109 draw_end);
110 }
111 } else {
112 AALINE(x1, y1, x2, y2,
113 DRAW_FASTSETPIXELXY4, DRAW_SETPIXELXY4_BLEND_RGB,
114 draw_end);
115 }
116 }
117 }
118
119 typedef void (*DrawLineFunc) (SDL_Surface * dst,
120 int x1, int y1, int x2, int y2,
121 Uint32 color, SDL_bool draw_end);
122
123 static DrawLineFunc
124 SDL_CalculateDrawLineFunc(const SDL_PixelFormat * fmt)
125 {
126 switch (fmt->BytesPerPixel) {
127 case 1:
128 if (fmt->BitsPerPixel < 8) {
129 break;
130 }
131 return SDL_DrawLine1;
132 case 2:
133 return SDL_DrawLine2;
134 case 4:
135 return SDL_DrawLine4;
136 }
137 return NULL;
138 }
139
140 int
141 SDL_DrawLine(SDL_Surface * dst, int x1, int y1, int x2, int y2, Uint32 color)
142 {
143 DrawLineFunc func;
144
145 if (!dst) {
146 SDL_SetError("SDL_DrawLine(): Passed NULL destination surface");
147 return -1;
148 }
149
150 func = SDL_CalculateDrawLineFunc(dst->format);
151 if (!func) {
152 SDL_SetError("SDL_DrawLine(): Unsupported surface format");
153 return -1;
154 }
155
156 /* Perform clipping */
157 /* FIXME: We don't actually want to clip, as it may change line slope */
158 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
159 return 0;
160 }
161
162 func(dst, x1, y1, x2, y2, color, SDL_TRUE);
163 return 0;
164 }
165
166 int
167 SDL_DrawLines(SDL_Surface * dst, const SDL_Point * points, int count,
168 Uint32 color)
169 {
170 int i;
171 int x1, y1;
172 int x2, y2;
173 SDL_bool draw_end;
174 DrawLineFunc func;
175
176 if (!dst) {
177 SDL_SetError("SDL_DrawLines(): Passed NULL destination surface");
178 return -1;
179 }
180
181 func = SDL_CalculateDrawLineFunc(dst->format);
182 if (!func) {
183 SDL_SetError("SDL_DrawLines(): Unsupported surface format");
184 return -1;
185 }
186
187 for (i = 1; i < count; ++i) {
188 x1 = points[i-1].x;
189 y1 = points[i-1].y;
190 x2 = points[i].x;
191 y2 = points[i].y;
192
193 /* Perform clipping */
194 /* FIXME: We don't actually want to clip, as it may change line slope */
195 if (!SDL_IntersectRectAndLine(&dst->clip_rect, &x1, &y1, &x2, &y2)) {
196 continue;
197 }
198
199 /* Draw the end if it was clipped */
200 draw_end = (x2 != points[i].x || y2 != points[i].y);
201
202 func(dst, x1, y1, x2, y2, color, draw_end);
203 }
204 if (points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
205 SDL_DrawPoint(dst, points[count-1].x, points[count-1].y, color);
206 }
207 return 0;
208 }
209
210 /* vi: set ts=4 sw=4 expandtab: */