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