slouken@2898
|
1 |
/*
|
slouken@5535
|
2 |
Simple DirectMedia Layer
|
slouken@5535
|
3 |
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
|
slouken@2898
|
4 |
|
slouken@5535
|
5 |
This software is provided 'as-is', without any express or implied
|
slouken@5535
|
6 |
warranty. In no event will the authors be held liable for any damages
|
slouken@5535
|
7 |
arising from the use of this software.
|
slouken@2898
|
8 |
|
slouken@5535
|
9 |
Permission is granted to anyone to use this software for any purpose,
|
slouken@5535
|
10 |
including commercial applications, and to alter it and redistribute it
|
slouken@5535
|
11 |
freely, subject to the following restrictions:
|
slouken@2898
|
12 |
|
slouken@5535
|
13 |
1. The origin of this software must not be misrepresented; you must not
|
slouken@5535
|
14 |
claim that you wrote the original software. If you use this software
|
slouken@5535
|
15 |
in a product, an acknowledgment in the product documentation would be
|
slouken@5535
|
16 |
appreciated but is not required.
|
slouken@5535
|
17 |
2. Altered source versions must be plainly marked as such, and must not be
|
slouken@5535
|
18 |
misrepresented as being the original software.
|
slouken@5535
|
19 |
3. This notice may not be removed or altered from any source distribution.
|
slouken@2898
|
20 |
*/
|
slouken@2898
|
21 |
#include "SDL_config.h"
|
slouken@2898
|
22 |
|
slouken@5163
|
23 |
#include "../../video/SDL_blit.h"
|
slouken@2898
|
24 |
|
slouken@2898
|
25 |
/* This code assumes that r, g, b, a are the source color,
|
slouken@2898
|
26 |
* and in the blend and add case, the RGB values are premultiplied by a.
|
slouken@2898
|
27 |
*/
|
slouken@2898
|
28 |
|
slouken@2898
|
29 |
#define DRAW_MUL(_a, _b) (((unsigned)(_a)*(_b))/255)
|
slouken@2898
|
30 |
|
slouken@3596
|
31 |
#define DRAW_FASTSETPIXEL(type) \
|
slouken@3596
|
32 |
*pixel = (type) color
|
slouken@3596
|
33 |
|
slouken@3596
|
34 |
#define DRAW_FASTSETPIXEL1 DRAW_FASTSETPIXEL(Uint8)
|
slouken@3596
|
35 |
#define DRAW_FASTSETPIXEL2 DRAW_FASTSETPIXEL(Uint16)
|
slouken@3596
|
36 |
#define DRAW_FASTSETPIXEL4 DRAW_FASTSETPIXEL(Uint32)
|
slouken@2901
|
37 |
|
slouken@3596
|
38 |
#define DRAW_FASTSETPIXELXY(x, y, type, bpp, color) \
|
slouken@3596
|
39 |
*(type *)((Uint8 *)dst->pixels + (y) * dst->pitch \
|
slouken@3596
|
40 |
+ (x) * bpp) = (type) color
|
slouken@3596
|
41 |
|
slouken@3596
|
42 |
#define DRAW_FASTSETPIXELXY1(x, y) DRAW_FASTSETPIXELXY(x, y, Uint8, 1, color)
|
slouken@3596
|
43 |
#define DRAW_FASTSETPIXELXY2(x, y) DRAW_FASTSETPIXELXY(x, y, Uint16, 2, color)
|
slouken@3596
|
44 |
#define DRAW_FASTSETPIXELXY4(x, y) DRAW_FASTSETPIXELXY(x, y, Uint32, 4, color)
|
slouken@2901
|
45 |
|
slouken@2898
|
46 |
#define DRAW_SETPIXEL(setpixel) \
|
slouken@2898
|
47 |
do { \
|
slouken@2898
|
48 |
unsigned sr = r, sg = g, sb = b, sa = a; \
|
slouken@2898
|
49 |
setpixel; \
|
slouken@2898
|
50 |
} while (0)
|
slouken@2898
|
51 |
|
slouken@2898
|
52 |
#define DRAW_SETPIXEL_BLEND(getpixel, setpixel) \
|
slouken@2898
|
53 |
do { \
|
slouken@2898
|
54 |
unsigned sr, sg, sb, sa; sa; \
|
slouken@2898
|
55 |
getpixel; \
|
slouken@2898
|
56 |
sr = DRAW_MUL(inva, sr) + r; \
|
slouken@2898
|
57 |
sg = DRAW_MUL(inva, sg) + g; \
|
slouken@2898
|
58 |
sb = DRAW_MUL(inva, sb) + b; \
|
slouken@2898
|
59 |
setpixel; \
|
slouken@2898
|
60 |
} while (0)
|
slouken@2898
|
61 |
|
slouken@2898
|
62 |
#define DRAW_SETPIXEL_ADD(getpixel, setpixel) \
|
slouken@2898
|
63 |
do { \
|
slouken@2898
|
64 |
unsigned sr, sg, sb, sa; sa; \
|
slouken@2898
|
65 |
getpixel; \
|
slouken@2898
|
66 |
sr += r; if (sr > 0xff) sr = 0xff; \
|
slouken@2898
|
67 |
sg += g; if (sg > 0xff) sg = 0xff; \
|
slouken@2898
|
68 |
sb += b; if (sb > 0xff) sb = 0xff; \
|
slouken@2898
|
69 |
setpixel; \
|
slouken@2898
|
70 |
} while (0)
|
slouken@2898
|
71 |
|
slouken@5184
|
72 |
#define DRAW_SETPIXEL_MOD(getpixel, setpixel) \
|
slouken@5184
|
73 |
do { \
|
slouken@5184
|
74 |
unsigned sr, sg, sb, sa; sa; \
|
slouken@5184
|
75 |
getpixel; \
|
slouken@5184
|
76 |
sr = DRAW_MUL(sr, r); \
|
slouken@5184
|
77 |
sg = DRAW_MUL(sg, g); \
|
slouken@5184
|
78 |
sb = DRAW_MUL(sb, b); \
|
slouken@5184
|
79 |
setpixel; \
|
slouken@5184
|
80 |
} while (0)
|
slouken@5184
|
81 |
|
slouken@2898
|
82 |
#define DRAW_SETPIXELXY(x, y, type, bpp, op) \
|
slouken@2898
|
83 |
do { \
|
slouken@3596
|
84 |
type *pixel = (type *)((Uint8 *)dst->pixels + (y) * dst->pitch \
|
slouken@3596
|
85 |
+ (x) * bpp); \
|
slouken@2898
|
86 |
op; \
|
slouken@2898
|
87 |
} while (0)
|
slouken@2898
|
88 |
|
slouken@2898
|
89 |
/*
|
slouken@2898
|
90 |
* Define draw operators for RGB555
|
slouken@2898
|
91 |
*/
|
slouken@2898
|
92 |
|
slouken@2898
|
93 |
#define DRAW_SETPIXEL_RGB555 \
|
slouken@2898
|
94 |
DRAW_SETPIXEL(RGB555_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
95 |
|
slouken@2898
|
96 |
#define DRAW_SETPIXEL_BLEND_RGB555 \
|
slouken@2898
|
97 |
DRAW_SETPIXEL_BLEND(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
|
slouken@2898
|
98 |
RGB555_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
99 |
|
slouken@2898
|
100 |
#define DRAW_SETPIXEL_ADD_RGB555 \
|
slouken@2898
|
101 |
DRAW_SETPIXEL_ADD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
|
slouken@2898
|
102 |
RGB555_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
103 |
|
slouken@5184
|
104 |
#define DRAW_SETPIXEL_MOD_RGB555 \
|
slouken@5184
|
105 |
DRAW_SETPIXEL_MOD(RGB_FROM_RGB555(*pixel, sr, sg, sb), \
|
slouken@5184
|
106 |
RGB555_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@5184
|
107 |
|
slouken@2898
|
108 |
#define DRAW_SETPIXELXY_RGB555(x, y) \
|
slouken@2898
|
109 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB555)
|
slouken@2898
|
110 |
|
slouken@2898
|
111 |
#define DRAW_SETPIXELXY_BLEND_RGB555(x, y) \
|
slouken@2898
|
112 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB555)
|
slouken@2898
|
113 |
|
slouken@2898
|
114 |
#define DRAW_SETPIXELXY_ADD_RGB555(x, y) \
|
slouken@2898
|
115 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB555)
|
slouken@2898
|
116 |
|
slouken@5184
|
117 |
#define DRAW_SETPIXELXY_MOD_RGB555(x, y) \
|
slouken@5184
|
118 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB555)
|
slouken@5184
|
119 |
|
slouken@2898
|
120 |
/*
|
slouken@2898
|
121 |
* Define draw operators for RGB565
|
slouken@2898
|
122 |
*/
|
slouken@2898
|
123 |
|
slouken@2898
|
124 |
#define DRAW_SETPIXEL_RGB565 \
|
slouken@2898
|
125 |
DRAW_SETPIXEL(RGB565_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
126 |
|
slouken@2898
|
127 |
#define DRAW_SETPIXEL_BLEND_RGB565 \
|
slouken@2898
|
128 |
DRAW_SETPIXEL_BLEND(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
|
slouken@2898
|
129 |
RGB565_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
130 |
|
slouken@2898
|
131 |
#define DRAW_SETPIXEL_ADD_RGB565 \
|
slouken@2898
|
132 |
DRAW_SETPIXEL_ADD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
|
slouken@2898
|
133 |
RGB565_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
134 |
|
slouken@5184
|
135 |
#define DRAW_SETPIXEL_MOD_RGB565 \
|
slouken@5184
|
136 |
DRAW_SETPIXEL_MOD(RGB_FROM_RGB565(*pixel, sr, sg, sb), \
|
slouken@5184
|
137 |
RGB565_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@5184
|
138 |
|
slouken@2898
|
139 |
#define DRAW_SETPIXELXY_RGB565(x, y) \
|
slouken@2898
|
140 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB565)
|
slouken@2898
|
141 |
|
slouken@2898
|
142 |
#define DRAW_SETPIXELXY_BLEND_RGB565(x, y) \
|
slouken@2898
|
143 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB565)
|
slouken@2898
|
144 |
|
slouken@2898
|
145 |
#define DRAW_SETPIXELXY_ADD_RGB565(x, y) \
|
slouken@2898
|
146 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB565)
|
slouken@2898
|
147 |
|
slouken@5184
|
148 |
#define DRAW_SETPIXELXY_MOD_RGB565(x, y) \
|
slouken@5184
|
149 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB565)
|
slouken@5184
|
150 |
|
slouken@2898
|
151 |
/*
|
slouken@2898
|
152 |
* Define draw operators for RGB888
|
slouken@2898
|
153 |
*/
|
slouken@2898
|
154 |
|
slouken@2898
|
155 |
#define DRAW_SETPIXEL_RGB888 \
|
slouken@2898
|
156 |
DRAW_SETPIXEL(RGB888_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
157 |
|
slouken@2898
|
158 |
#define DRAW_SETPIXEL_BLEND_RGB888 \
|
slouken@2898
|
159 |
DRAW_SETPIXEL_BLEND(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
|
slouken@2898
|
160 |
RGB888_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
161 |
|
slouken@2898
|
162 |
#define DRAW_SETPIXEL_ADD_RGB888 \
|
slouken@2898
|
163 |
DRAW_SETPIXEL_ADD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
|
slouken@2898
|
164 |
RGB888_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@2898
|
165 |
|
slouken@5184
|
166 |
#define DRAW_SETPIXEL_MOD_RGB888 \
|
slouken@5184
|
167 |
DRAW_SETPIXEL_MOD(RGB_FROM_RGB888(*pixel, sr, sg, sb), \
|
slouken@5184
|
168 |
RGB888_FROM_RGB(*pixel, sr, sg, sb))
|
slouken@5184
|
169 |
|
slouken@2898
|
170 |
#define DRAW_SETPIXELXY_RGB888(x, y) \
|
slouken@2898
|
171 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB888)
|
slouken@2898
|
172 |
|
slouken@2898
|
173 |
#define DRAW_SETPIXELXY_BLEND_RGB888(x, y) \
|
slouken@2898
|
174 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB888)
|
slouken@2898
|
175 |
|
slouken@2898
|
176 |
#define DRAW_SETPIXELXY_ADD_RGB888(x, y) \
|
slouken@2898
|
177 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB888)
|
slouken@2898
|
178 |
|
slouken@5184
|
179 |
#define DRAW_SETPIXELXY_MOD_RGB888(x, y) \
|
slouken@5184
|
180 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB888)
|
slouken@5184
|
181 |
|
slouken@2898
|
182 |
/*
|
slouken@2899
|
183 |
* Define draw operators for ARGB8888
|
slouken@2899
|
184 |
*/
|
slouken@2899
|
185 |
|
slouken@2899
|
186 |
#define DRAW_SETPIXEL_ARGB8888 \
|
slouken@2899
|
187 |
DRAW_SETPIXEL(ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
|
slouken@2899
|
188 |
|
slouken@2899
|
189 |
#define DRAW_SETPIXEL_BLEND_ARGB8888 \
|
slouken@2899
|
190 |
DRAW_SETPIXEL_BLEND(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
|
slouken@2899
|
191 |
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
|
slouken@2899
|
192 |
|
slouken@2899
|
193 |
#define DRAW_SETPIXEL_ADD_ARGB8888 \
|
slouken@2899
|
194 |
DRAW_SETPIXEL_ADD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
|
slouken@2899
|
195 |
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
|
slouken@2899
|
196 |
|
slouken@5184
|
197 |
#define DRAW_SETPIXEL_MOD_ARGB8888 \
|
slouken@5184
|
198 |
DRAW_SETPIXEL_MOD(RGBA_FROM_ARGB8888(*pixel, sr, sg, sb, sa), \
|
slouken@5184
|
199 |
ARGB8888_FROM_RGBA(*pixel, sr, sg, sb, sa))
|
slouken@5184
|
200 |
|
slouken@2899
|
201 |
#define DRAW_SETPIXELXY_ARGB8888(x, y) \
|
slouken@2899
|
202 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ARGB8888)
|
slouken@2899
|
203 |
|
slouken@2899
|
204 |
#define DRAW_SETPIXELXY_BLEND_ARGB8888(x, y) \
|
slouken@2899
|
205 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_ARGB8888)
|
slouken@2899
|
206 |
|
slouken@2899
|
207 |
#define DRAW_SETPIXELXY_ADD_ARGB8888(x, y) \
|
slouken@2899
|
208 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_ARGB8888)
|
slouken@2899
|
209 |
|
slouken@5184
|
210 |
#define DRAW_SETPIXELXY_MOD_ARGB8888(x, y) \
|
slouken@5184
|
211 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_ARGB8888)
|
slouken@5184
|
212 |
|
slouken@2899
|
213 |
/*
|
slouken@2898
|
214 |
* Define draw operators for general RGB
|
slouken@2898
|
215 |
*/
|
slouken@2898
|
216 |
|
slouken@2898
|
217 |
#define DRAW_SETPIXEL_RGB \
|
slouken@2898
|
218 |
DRAW_SETPIXEL(PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
|
slouken@2898
|
219 |
|
slouken@2898
|
220 |
#define DRAW_SETPIXEL_BLEND_RGB \
|
slouken@2898
|
221 |
DRAW_SETPIXEL_BLEND(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
|
slouken@2898
|
222 |
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
|
slouken@2898
|
223 |
|
slouken@2898
|
224 |
#define DRAW_SETPIXEL_ADD_RGB \
|
slouken@2898
|
225 |
DRAW_SETPIXEL_ADD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
|
slouken@2898
|
226 |
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
|
slouken@2898
|
227 |
|
slouken@5184
|
228 |
#define DRAW_SETPIXEL_MOD_RGB \
|
slouken@5184
|
229 |
DRAW_SETPIXEL_MOD(RGB_FROM_PIXEL(*pixel, fmt, sr, sg, sb), \
|
slouken@5184
|
230 |
PIXEL_FROM_RGB(*pixel, fmt, sr, sg, sb))
|
slouken@5184
|
231 |
|
slouken@2898
|
232 |
#define DRAW_SETPIXELXY2_RGB(x, y) \
|
slouken@2898
|
233 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_RGB)
|
slouken@2898
|
234 |
|
slouken@2898
|
235 |
#define DRAW_SETPIXELXY4_RGB(x, y) \
|
slouken@2898
|
236 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGB)
|
slouken@2898
|
237 |
|
slouken@2898
|
238 |
#define DRAW_SETPIXELXY2_BLEND_RGB(x, y) \
|
slouken@2898
|
239 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_BLEND_RGB)
|
slouken@2898
|
240 |
|
slouken@2898
|
241 |
#define DRAW_SETPIXELXY4_BLEND_RGB(x, y) \
|
slouken@2898
|
242 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGB)
|
slouken@2898
|
243 |
|
slouken@2898
|
244 |
#define DRAW_SETPIXELXY2_ADD_RGB(x, y) \
|
slouken@2898
|
245 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_ADD_RGB)
|
slouken@2898
|
246 |
|
slouken@2898
|
247 |
#define DRAW_SETPIXELXY4_ADD_RGB(x, y) \
|
slouken@2898
|
248 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGB)
|
slouken@2898
|
249 |
|
slouken@5184
|
250 |
#define DRAW_SETPIXELXY2_MOD_RGB(x, y) \
|
slouken@5184
|
251 |
DRAW_SETPIXELXY(x, y, Uint16, 2, DRAW_SETPIXEL_MOD_RGB)
|
slouken@5184
|
252 |
|
slouken@5184
|
253 |
#define DRAW_SETPIXELXY4_MOD_RGB(x, y) \
|
slouken@5184
|
254 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGB)
|
slouken@5184
|
255 |
|
slouken@2898
|
256 |
|
slouken@2898
|
257 |
/*
|
slouken@2898
|
258 |
* Define draw operators for general RGBA
|
slouken@2898
|
259 |
*/
|
slouken@2898
|
260 |
|
slouken@2898
|
261 |
#define DRAW_SETPIXEL_RGBA \
|
slouken@2898
|
262 |
DRAW_SETPIXEL(PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
|
slouken@2898
|
263 |
|
slouken@2898
|
264 |
#define DRAW_SETPIXEL_BLEND_RGBA \
|
slouken@2898
|
265 |
DRAW_SETPIXEL_BLEND(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
|
slouken@2898
|
266 |
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
|
slouken@2898
|
267 |
|
slouken@2898
|
268 |
#define DRAW_SETPIXEL_ADD_RGBA \
|
slouken@2898
|
269 |
DRAW_SETPIXEL_ADD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
|
slouken@2898
|
270 |
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
|
slouken@2898
|
271 |
|
slouken@5184
|
272 |
#define DRAW_SETPIXEL_MOD_RGBA \
|
slouken@5184
|
273 |
DRAW_SETPIXEL_MOD(RGBA_FROM_PIXEL(*pixel, fmt, sr, sg, sb, sa), \
|
slouken@5184
|
274 |
PIXEL_FROM_RGBA(*pixel, fmt, sr, sg, sb, sa))
|
slouken@5184
|
275 |
|
slouken@2898
|
276 |
#define DRAW_SETPIXELXY4_RGBA(x, y) \
|
slouken@2898
|
277 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_RGBA)
|
slouken@2898
|
278 |
|
slouken@2898
|
279 |
#define DRAW_SETPIXELXY4_BLEND_RGBA(x, y) \
|
slouken@2898
|
280 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_BLEND_RGBA)
|
slouken@2898
|
281 |
|
slouken@2898
|
282 |
#define DRAW_SETPIXELXY4_ADD_RGBA(x, y) \
|
slouken@2898
|
283 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_ADD_RGBA)
|
slouken@2898
|
284 |
|
slouken@5184
|
285 |
#define DRAW_SETPIXELXY4_MOD_RGBA(x, y) \
|
slouken@5184
|
286 |
DRAW_SETPIXELXY(x, y, Uint32, 4, DRAW_SETPIXEL_MOD_RGBA)
|
slouken@5184
|
287 |
|
slouken@2898
|
288 |
/*
|
slouken@2898
|
289 |
* Define line drawing macro
|
slouken@2898
|
290 |
*/
|
slouken@2898
|
291 |
|
slouken@2898
|
292 |
#define ABS(_x) ((_x) < 0 ? -(_x) : (_x))
|
slouken@2898
|
293 |
|
slouken@3596
|
294 |
/* Horizontal line */
|
slouken@3596
|
295 |
#define HLINE(type, op, draw_end) \
|
slouken@3596
|
296 |
{ \
|
slouken@3596
|
297 |
int length; \
|
slouken@3596
|
298 |
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
|
slouken@3596
|
299 |
type *pixel; \
|
slouken@3596
|
300 |
if (x1 <= x2) { \
|
slouken@3596
|
301 |
pixel = (type *)dst->pixels + y1 * pitch + x1; \
|
slouken@3596
|
302 |
length = draw_end ? (x2-x1+1) : (x2-x1); \
|
slouken@3596
|
303 |
} else { \
|
slouken@3596
|
304 |
pixel = (type *)dst->pixels + y1 * pitch + x2; \
|
slouken@3596
|
305 |
if (!draw_end) { \
|
slouken@3596
|
306 |
++pixel; \
|
slouken@3596
|
307 |
} \
|
slouken@3596
|
308 |
length = draw_end ? (x1-x2+1) : (x1-x2); \
|
slouken@3596
|
309 |
} \
|
slouken@3596
|
310 |
while (length--) { \
|
slouken@3596
|
311 |
op; \
|
slouken@3596
|
312 |
++pixel; \
|
slouken@3596
|
313 |
} \
|
slouken@3596
|
314 |
}
|
slouken@3596
|
315 |
|
slouken@3596
|
316 |
/* Vertical line */
|
slouken@3596
|
317 |
#define VLINE(type, op, draw_end) \
|
slouken@3596
|
318 |
{ \
|
slouken@3596
|
319 |
int length; \
|
slouken@3596
|
320 |
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
|
slouken@3596
|
321 |
type *pixel; \
|
slouken@3596
|
322 |
if (y1 <= y2) { \
|
slouken@3596
|
323 |
pixel = (type *)dst->pixels + y1 * pitch + x1; \
|
slouken@3596
|
324 |
length = draw_end ? (y2-y1+1) : (y2-y1); \
|
slouken@3596
|
325 |
} else { \
|
slouken@3596
|
326 |
pixel = (type *)dst->pixels + y2 * pitch + x1; \
|
slouken@3596
|
327 |
if (!draw_end) { \
|
slouken@3596
|
328 |
pixel += pitch; \
|
slouken@3596
|
329 |
} \
|
slouken@3596
|
330 |
length = draw_end ? (y1-y2+1) : (y1-y2); \
|
slouken@3596
|
331 |
} \
|
slouken@3596
|
332 |
while (length--) { \
|
slouken@3596
|
333 |
op; \
|
slouken@3596
|
334 |
pixel += pitch; \
|
slouken@3596
|
335 |
} \
|
slouken@3596
|
336 |
}
|
slouken@3596
|
337 |
|
slouken@3596
|
338 |
/* Diagonal line */
|
slouken@3596
|
339 |
#define DLINE(type, op, draw_end) \
|
slouken@3596
|
340 |
{ \
|
slouken@3596
|
341 |
int length; \
|
slouken@3596
|
342 |
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
|
slouken@3596
|
343 |
type *pixel; \
|
slouken@3596
|
344 |
if (y1 <= y2) { \
|
slouken@3596
|
345 |
pixel = (type *)dst->pixels + y1 * pitch + x1; \
|
slouken@3596
|
346 |
if (x1 <= x2) { \
|
slouken@3596
|
347 |
++pitch; \
|
slouken@3596
|
348 |
} else { \
|
slouken@3596
|
349 |
--pitch; \
|
slouken@3596
|
350 |
} \
|
slouken@3596
|
351 |
length = (y2-y1); \
|
slouken@3596
|
352 |
} else { \
|
slouken@3596
|
353 |
pixel = (type *)dst->pixels + y2 * pitch + x2; \
|
slouken@3596
|
354 |
if (x2 <= x1) { \
|
slouken@3596
|
355 |
++pitch; \
|
slouken@3596
|
356 |
} else { \
|
slouken@3596
|
357 |
--pitch; \
|
slouken@3596
|
358 |
} \
|
slouken@3596
|
359 |
if (!draw_end) { \
|
slouken@3596
|
360 |
pixel += pitch; \
|
slouken@3596
|
361 |
} \
|
slouken@3596
|
362 |
length = (y1-y2); \
|
slouken@3596
|
363 |
} \
|
slouken@3596
|
364 |
if (draw_end) { \
|
slouken@3596
|
365 |
++length; \
|
slouken@3596
|
366 |
} \
|
slouken@3596
|
367 |
while (length--) { \
|
slouken@3596
|
368 |
op; \
|
slouken@3596
|
369 |
pixel += pitch; \
|
slouken@3596
|
370 |
} \
|
slouken@3596
|
371 |
}
|
slouken@3596
|
372 |
|
slouken@3596
|
373 |
/* Bresenham's line algorithm */
|
slouken@3596
|
374 |
#define BLINE(x1, y1, x2, y2, op, draw_end) \
|
slouken@2898
|
375 |
{ \
|
slouken@2903
|
376 |
int i, deltax, deltay, numpixels; \
|
slouken@2903
|
377 |
int d, dinc1, dinc2; \
|
slouken@2903
|
378 |
int x, xinc1, xinc2; \
|
slouken@2903
|
379 |
int y, yinc1, yinc2; \
|
slouken@2903
|
380 |
\
|
slouken@2903
|
381 |
deltax = ABS(x2 - x1); \
|
slouken@2903
|
382 |
deltay = ABS(y2 - y1); \
|
slouken@2898
|
383 |
\
|
slouken@2903
|
384 |
if (deltax >= deltay) { \
|
slouken@2903
|
385 |
numpixels = deltax + 1; \
|
slouken@2903
|
386 |
d = (2 * deltay) - deltax; \
|
slouken@2903
|
387 |
dinc1 = deltay * 2; \
|
slouken@2903
|
388 |
dinc2 = (deltay - deltax) * 2; \
|
slouken@2903
|
389 |
xinc1 = 1; \
|
slouken@2903
|
390 |
xinc2 = 1; \
|
slouken@2903
|
391 |
yinc1 = 0; \
|
slouken@2903
|
392 |
yinc2 = 1; \
|
slouken@2898
|
393 |
} else { \
|
slouken@2903
|
394 |
numpixels = deltay + 1; \
|
slouken@2903
|
395 |
d = (2 * deltax) - deltay; \
|
slouken@2903
|
396 |
dinc1 = deltax * 2; \
|
slouken@2903
|
397 |
dinc2 = (deltax - deltay) * 2; \
|
slouken@2903
|
398 |
xinc1 = 0; \
|
slouken@2903
|
399 |
xinc2 = 1; \
|
slouken@2903
|
400 |
yinc1 = 1; \
|
slouken@2903
|
401 |
yinc2 = 1; \
|
slouken@2898
|
402 |
} \
|
slouken@2903
|
403 |
\
|
slouken@2903
|
404 |
if (x1 > x2) { \
|
slouken@2903
|
405 |
xinc1 = -xinc1; \
|
slouken@2903
|
406 |
xinc2 = -xinc2; \
|
slouken@2903
|
407 |
} \
|
slouken@2903
|
408 |
if (y1 > y2) { \
|
slouken@2903
|
409 |
yinc1 = -yinc1; \
|
slouken@2903
|
410 |
yinc2 = -yinc2; \
|
slouken@2898
|
411 |
} \
|
slouken@2903
|
412 |
\
|
slouken@2903
|
413 |
x = x1; \
|
slouken@2903
|
414 |
y = y1; \
|
slouken@2903
|
415 |
\
|
slouken@3594
|
416 |
if (!draw_end) { \
|
slouken@3594
|
417 |
--numpixels; \
|
slouken@3594
|
418 |
} \
|
slouken@3063
|
419 |
for (i = 0; i < numpixels; ++i) { \
|
slouken@2903
|
420 |
op(x, y); \
|
slouken@2903
|
421 |
if (d < 0) { \
|
slouken@2903
|
422 |
d += dinc1; \
|
slouken@2903
|
423 |
x += xinc1; \
|
slouken@2903
|
424 |
y += yinc1; \
|
slouken@2903
|
425 |
} else { \
|
slouken@2903
|
426 |
d += dinc2; \
|
slouken@2903
|
427 |
x += xinc2; \
|
slouken@2903
|
428 |
y += yinc2; \
|
slouken@2898
|
429 |
} \
|
slouken@2898
|
430 |
} \
|
slouken@2898
|
431 |
}
|
slouken@2898
|
432 |
|
slouken@3596
|
433 |
/* Xiaolin Wu's line algorithm, based on Michael Abrash's implementation */
|
slouken@3596
|
434 |
#define WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
|
slouken@3596
|
435 |
{ \
|
slouken@3596
|
436 |
Uint16 ErrorAdj, ErrorAcc; \
|
slouken@3596
|
437 |
Uint16 ErrorAccTemp, Weighting; \
|
slouken@3596
|
438 |
int DeltaX, DeltaY, Temp, XDir; \
|
slouken@3596
|
439 |
unsigned r, g, b, a, inva; \
|
slouken@3596
|
440 |
\
|
slouken@3596
|
441 |
/* Draw the initial pixel, which is always exactly intersected by \
|
slouken@3596
|
442 |
the line and so needs no weighting */ \
|
slouken@3596
|
443 |
opaque_op(x1, y1); \
|
slouken@3596
|
444 |
\
|
slouken@3596
|
445 |
/* Draw the final pixel, which is always exactly intersected by the line \
|
slouken@3596
|
446 |
and so needs no weighting */ \
|
slouken@3596
|
447 |
if (draw_end) { \
|
slouken@3596
|
448 |
opaque_op(x2, y2); \
|
slouken@3596
|
449 |
} \
|
slouken@3596
|
450 |
\
|
slouken@3596
|
451 |
/* Make sure the line runs top to bottom */ \
|
slouken@3596
|
452 |
if (y1 > y2) { \
|
slouken@3596
|
453 |
Temp = y1; y1 = y2; y2 = Temp; \
|
slouken@3596
|
454 |
Temp = x1; x1 = x2; x2 = Temp; \
|
slouken@3596
|
455 |
} \
|
slouken@3596
|
456 |
DeltaY = y2 - y1; \
|
slouken@3596
|
457 |
\
|
slouken@3596
|
458 |
if ((DeltaX = x2 - x1) >= 0) { \
|
slouken@3596
|
459 |
XDir = 1; \
|
slouken@3596
|
460 |
} else { \
|
slouken@3596
|
461 |
XDir = -1; \
|
slouken@3596
|
462 |
DeltaX = -DeltaX; /* make DeltaX positive */ \
|
slouken@3596
|
463 |
} \
|
slouken@3596
|
464 |
\
|
slouken@3596
|
465 |
/* line is not horizontal, diagonal, or vertical */ \
|
slouken@3596
|
466 |
ErrorAcc = 0; /* initialize the line error accumulator to 0 */ \
|
slouken@3596
|
467 |
\
|
slouken@3596
|
468 |
/* Is this an X-major or Y-major line? */ \
|
slouken@3596
|
469 |
if (DeltaY > DeltaX) { \
|
slouken@3596
|
470 |
/* Y-major line; calculate 16-bit fixed-point fractional part of a \
|
slouken@3596
|
471 |
pixel that X advances each time Y advances 1 pixel, truncating the \
|
slouken@3596
|
472 |
result so that we won't overrun the endpoint along the X axis */ \
|
slouken@3596
|
473 |
ErrorAdj = ((unsigned long) DeltaX << 16) / (unsigned long) DeltaY; \
|
slouken@3596
|
474 |
/* Draw all pixels other than the first and last */ \
|
slouken@3596
|
475 |
while (--DeltaY) { \
|
slouken@3596
|
476 |
ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ \
|
slouken@3596
|
477 |
ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \
|
slouken@3596
|
478 |
if (ErrorAcc <= ErrorAccTemp) { \
|
slouken@3596
|
479 |
/* The error accumulator turned over, so advance the X coord */ \
|
slouken@3596
|
480 |
x1 += XDir; \
|
slouken@3596
|
481 |
} \
|
slouken@3596
|
482 |
y1++; /* Y-major, so always advance Y */ \
|
slouken@3596
|
483 |
/* The IntensityBits most significant bits of ErrorAcc give us the \
|
slouken@3596
|
484 |
intensity weighting for this pixel, and the complement of the \
|
slouken@3596
|
485 |
weighting for the paired pixel */ \
|
slouken@3596
|
486 |
Weighting = ErrorAcc >> 8; \
|
slouken@3596
|
487 |
{ \
|
slouken@3596
|
488 |
a = DRAW_MUL(_a, (Weighting ^ 255)); \
|
slouken@3596
|
489 |
r = DRAW_MUL(_r, a); \
|
slouken@3596
|
490 |
g = DRAW_MUL(_g, a); \
|
slouken@3596
|
491 |
b = DRAW_MUL(_b, a); \
|
slouken@3596
|
492 |
inva = (a ^ 0xFF); \
|
slouken@3596
|
493 |
blend_op(x1, y1); \
|
slouken@3596
|
494 |
} \
|
slouken@3596
|
495 |
{ \
|
slouken@3596
|
496 |
a = DRAW_MUL(_a, Weighting); \
|
slouken@3596
|
497 |
r = DRAW_MUL(_r, a); \
|
slouken@3596
|
498 |
g = DRAW_MUL(_g, a); \
|
slouken@3596
|
499 |
b = DRAW_MUL(_b, a); \
|
slouken@3596
|
500 |
inva = (a ^ 0xFF); \
|
slouken@3596
|
501 |
blend_op(x1 + XDir, y1); \
|
slouken@3596
|
502 |
} \
|
slouken@3596
|
503 |
} \
|
slouken@3596
|
504 |
} else { \
|
slouken@3596
|
505 |
/* X-major line; calculate 16-bit fixed-point fractional part of a \
|
slouken@3596
|
506 |
pixel that Y advances each time X advances 1 pixel, truncating the \
|
slouken@3596
|
507 |
result to avoid overrunning the endpoint along the X axis */ \
|
slouken@3596
|
508 |
ErrorAdj = ((unsigned long) DeltaY << 16) / (unsigned long) DeltaX; \
|
slouken@3596
|
509 |
/* Draw all pixels other than the first and last */ \
|
slouken@3596
|
510 |
while (--DeltaX) { \
|
slouken@3596
|
511 |
ErrorAccTemp = ErrorAcc; /* remember currrent accumulated error */ \
|
slouken@3596
|
512 |
ErrorAcc += ErrorAdj; /* calculate error for next pixel */ \
|
slouken@3596
|
513 |
if (ErrorAcc <= ErrorAccTemp) { \
|
slouken@3596
|
514 |
/* The error accumulator turned over, so advance the Y coord */ \
|
slouken@3596
|
515 |
y1++; \
|
slouken@3596
|
516 |
} \
|
slouken@3596
|
517 |
x1 += XDir; /* X-major, so always advance X */ \
|
slouken@3596
|
518 |
/* The IntensityBits most significant bits of ErrorAcc give us the \
|
slouken@3596
|
519 |
intensity weighting for this pixel, and the complement of the \
|
slouken@3596
|
520 |
weighting for the paired pixel */ \
|
slouken@3596
|
521 |
Weighting = ErrorAcc >> 8; \
|
slouken@3596
|
522 |
{ \
|
slouken@3596
|
523 |
a = DRAW_MUL(_a, (Weighting ^ 255)); \
|
slouken@3596
|
524 |
r = DRAW_MUL(_r, a); \
|
slouken@3596
|
525 |
g = DRAW_MUL(_g, a); \
|
slouken@3596
|
526 |
b = DRAW_MUL(_b, a); \
|
slouken@3596
|
527 |
inva = (a ^ 0xFF); \
|
slouken@3596
|
528 |
blend_op(x1, y1); \
|
slouken@3596
|
529 |
} \
|
slouken@3596
|
530 |
{ \
|
slouken@3596
|
531 |
a = DRAW_MUL(_a, Weighting); \
|
slouken@3596
|
532 |
r = DRAW_MUL(_r, a); \
|
slouken@3596
|
533 |
g = DRAW_MUL(_g, a); \
|
slouken@3596
|
534 |
b = DRAW_MUL(_b, a); \
|
slouken@3596
|
535 |
inva = (a ^ 0xFF); \
|
slouken@3596
|
536 |
blend_op(x1, y1 + 1); \
|
slouken@3596
|
537 |
} \
|
slouken@3593
|
538 |
} \
|
slouken@3593
|
539 |
} \
|
slouken@3596
|
540 |
}
|
slouken@3596
|
541 |
|
slouken@3596
|
542 |
#ifdef AA_LINES
|
slouken@3596
|
543 |
#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
|
slouken@3596
|
544 |
WULINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end)
|
slouken@3596
|
545 |
#else
|
slouken@3596
|
546 |
#define AALINE(x1, y1, x2, y2, opaque_op, blend_op, draw_end) \
|
slouken@3596
|
547 |
BLINE(x1, y1, x2, y2, opaque_op, draw_end)
|
slouken@3596
|
548 |
#endif
|
slouken@3593
|
549 |
|
slouken@3593
|
550 |
/*
|
slouken@3593
|
551 |
* Define fill rect macro
|
slouken@2898
|
552 |
*/
|
slouken@2898
|
553 |
|
slouken@2900
|
554 |
#define FILLRECT(type, op) \
|
slouken@2898
|
555 |
do { \
|
slouken@3536
|
556 |
int width = rect->w; \
|
slouken@3536
|
557 |
int height = rect->h; \
|
slouken@2898
|
558 |
int pitch = (dst->pitch / dst->format->BytesPerPixel); \
|
slouken@2898
|
559 |
int skip = pitch - width; \
|
slouken@3536
|
560 |
type *pixel = (type *)dst->pixels + rect->y * pitch + rect->x; \
|
slouken@2898
|
561 |
while (height--) { \
|
slouken@2898
|
562 |
{ int n = (width+3)/4; \
|
slouken@2898
|
563 |
switch (width & 3) { \
|
slouken@2898
|
564 |
case 0: do { op; pixel++; \
|
slouken@2898
|
565 |
case 3: op; pixel++; \
|
slouken@2898
|
566 |
case 2: op; pixel++; \
|
slouken@2898
|
567 |
case 1: op; pixel++; \
|
slouken@2898
|
568 |
} while ( --n > 0 ); \
|
slouken@2898
|
569 |
} \
|
slouken@2898
|
570 |
} \
|
slouken@2898
|
571 |
pixel += skip; \
|
slouken@2898
|
572 |
} \
|
slouken@2898
|
573 |
} while (0)
|
slouken@2898
|
574 |
|
slouken@2898
|
575 |
/* vi: set ts=4 sw=4 expandtab: */
|