2 pygame - Python Game Library
3 Copyright (C) 2000-2001 Pete Shinners
4 Copyright (C) 2007 Marcus von Appen
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the Free
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 /* This is defined in SDL.h */
28 #if defined(_POSIX_C_SOURCE)
29 #undef _POSIX_C_SOURCE
36 #define PYGAME_BLEND_ADD 0x1
37 #define PYGAME_BLEND_SUB 0x2
38 #define PYGAME_BLEND_MULT 0x3
39 #define PYGAME_BLEND_MIN 0x4
40 #define PYGAME_BLEND_MAX 0x5
42 #define PYGAME_BLEND_RGB_ADD 0x1
43 #define PYGAME_BLEND_RGB_SUB 0x2
44 #define PYGAME_BLEND_RGB_MULT 0x3
45 #define PYGAME_BLEND_RGB_MIN 0x4
46 #define PYGAME_BLEND_RGB_MAX 0x5
48 #define PYGAME_BLEND_RGBA_ADD 0x6
49 #define PYGAME_BLEND_RGBA_SUB 0x7
50 #define PYGAME_BLEND_RGBA_MULT 0x8
51 #define PYGAME_BLEND_RGBA_MIN 0x9
52 #define PYGAME_BLEND_RGBA_MAX 0x10
53 #define PYGAME_BLEND_PREMULTIPLIED 0x11
54 #define PYGAME_BLEND_ALPHA_SDL2 0x12
60 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
61 #define GET_PIXEL_24(b) (b[0] + (b[1] << 8) + (b[2] << 16))
63 #define GET_PIXEL_24(b) (b[2] + (b[1] << 8) + (b[0] << 16))
66 #define GET_PIXEL(pxl, bpp, source) \
70 pxl = *((Uint16 *) (source)); \
73 pxl = *((Uint32 *) (source)); \
77 Uint8 *b = (Uint8 *) source; \
78 pxl = GET_PIXEL_24(b); \
84 #define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa) \
85 _sR = ((px & fmt->Rmask) >> fmt->Rshift); \
86 _sR = (_sR << fmt->Rloss) + (_sR >> (8 - (fmt->Rloss << 1))); \
87 _sG = ((px & fmt->Gmask) >> fmt->Gshift); \
88 _sG = (_sG << fmt->Gloss) + (_sG >> (8 - (fmt->Gloss << 1))); \
89 _sB = ((px & fmt->Bmask) >> fmt->Bshift); \
90 _sB = (_sB << fmt->Bloss) + (_sB >> (8 - (fmt->Bloss << 1))); \
93 _sA = ((px & fmt->Amask) >> fmt->Ashift); \
94 _sA = (_sA << fmt->Aloss) + (_sA >> (8 - (fmt->Aloss << 1))); \
101 #define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \
102 sr = _fmt->palette->colors[*((Uint8 *) (_src))].r; \
103 sg = _fmt->palette->colors[*((Uint8 *) (_src))].g; \
104 sb = _fmt->palette->colors[*((Uint8 *) (_src))].b; \
107 /* For 1 byte palette pixels */
108 #define SET_PIXELVAL(px, fmt, _dR, _dG, _dB, _dA) \
109 *(px) = (Uint8) SDL_MapRGB(fmt, _dR, _dG, _dB)
111 #define GET_PIXELVALS(_sR, _sG, _sB, _sA, px, fmt, ppa) \
112 SDL_GetRGBA(px, fmt, &(_sR), &(_sG), &(_sB), &(_sA)); \
117 #define GET_PIXELVALS_1(sr, sg, sb, sa, _src, _fmt) \
118 sr = _fmt->palette->colors[*((Uint8 *) (_src))].r; \
119 sg = _fmt->palette->colors[*((Uint8 *) (_src))].g; \
120 sb = _fmt->palette->colors[*((Uint8 *) (_src))].b; \
123 /* For 1 byte palette pixels */
124 #define SET_PIXELVAL(px, fmt, _dR, _dG, _dB, _dA) \
125 *(px) = (Uint8) SDL_MapRGBA(fmt, _dR, _dG, _dB, _dA)
126 #endif /* IS_SDLv2 */
135 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
136 #define SET_OFFSETS_24(or, og, ob, fmt) \
138 or = (fmt->Rshift == 0 ? 0 : \
139 fmt->Rshift == 8 ? 1 : \
141 og = (fmt->Gshift == 0 ? 0 : \
142 fmt->Gshift == 8 ? 1 : \
144 ob = (fmt->Bshift == 0 ? 0 : \
145 fmt->Bshift == 8 ? 1 : \
149 #define SET_OFFSETS_32(or, og, ob, fmt) \
151 or = (fmt->Rshift == 0 ? 0 : \
152 fmt->Rshift == 8 ? 1 : \
153 fmt->Rshift == 16 ? 2 : \
155 og = (fmt->Gshift == 0 ? 0 : \
156 fmt->Gshift == 8 ? 1 : \
157 fmt->Gshift == 16 ? 2 : \
159 ob = (fmt->Bshift == 0 ? 0 : \
160 fmt->Bshift == 8 ? 1 : \
161 fmt->Bshift == 16 ? 2 : \
165 #define SET_OFFSETS_24(or, og, ob, fmt) \
167 or = (fmt->Rshift == 0 ? 2 : \
168 fmt->Rshift == 8 ? 1 : \
170 og = (fmt->Gshift == 0 ? 2 : \
171 fmt->Gshift == 8 ? 1 : \
173 ob = (fmt->Bshift == 0 ? 2 : \
174 fmt->Bshift == 8 ? 1 : \
178 #define SET_OFFSETS_32(or, og, ob, fmt) \
180 or = (fmt->Rshift == 0 ? 3 : \
181 fmt->Rshift == 8 ? 2 : \
182 fmt->Rshift == 16 ? 1 : \
184 og = (fmt->Gshift == 0 ? 3 : \
185 fmt->Gshift == 8 ? 2 : \
186 fmt->Gshift == 16 ? 1 : \
188 ob = (fmt->Bshift == 0 ? 3 : \
189 fmt->Bshift == 8 ? 2 : \
190 fmt->Bshift == 16 ? 1 : \
196 #define CREATE_PIXEL(buf, r, g, b, a, bp, ft) \
200 *((Uint16 *) (buf)) = \
201 ((r >> ft->Rloss) << ft->Rshift) | \
202 ((g >> ft->Gloss) << ft->Gshift) | \
203 ((b >> ft->Bloss) << ft->Bshift) | \
204 ((a >> ft->Aloss) << ft->Ashift); \
207 *((Uint32 *) (buf)) = \
208 ((r >> ft->Rloss) << ft->Rshift) | \
209 ((g >> ft->Gloss) << ft->Gshift) | \
210 ((b >> ft->Bloss) << ft->Bshift) | \
211 ((a >> ft->Aloss) << ft->Ashift); \
215 /* Pretty good idea from Tom Duff :-). */
216 #define LOOP_UNROLLED4(code, n, width) \
217 n = (width + 3) / 4; \
227 /* Used in the srcbpp == dstbpp == 1 blend functions */
228 #define REPEAT_3(code) \
233 #define REPEAT_4(code) \
240 #define BLEND_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
241 tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \
242 tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \
243 tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255);
245 #define BLEND_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
246 tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \
247 tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \
248 tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0);
250 #define BLEND_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
251 dR = (dR && sR) ? (dR * sR) >> 8 : 0; \
252 dG = (dG && sG) ? (dG * sG) >> 8 : 0; \
253 dB = (dB && sB) ? (dB * sB) >> 8 : 0;
255 #define BLEND_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \
256 if(sR < dR) { dR = sR; } \
257 if(sG < dG) { dG = sG; } \
258 if(sB < dB) { dB = sB; }
260 #define BLEND_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \
261 if(sR > dR) { dR = sR; } \
262 if(sG > dG) { dG = sG; } \
263 if(sB > dB) { dB = sB; }
270 #define BLEND_RGBA_ADD(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
271 tmp = dR + sR; dR = (tmp <= 255 ? tmp : 255); \
272 tmp = dG + sG; dG = (tmp <= 255 ? tmp : 255); \
273 tmp = dB + sB; dB = (tmp <= 255 ? tmp : 255); \
274 tmp = dA + sA; dA = (tmp <= 255 ? tmp : 255);
276 #define BLEND_RGBA_SUB(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
277 tmp = dR - sR; dR = (tmp >= 0 ? tmp : 0); \
278 tmp = dG - sG; dG = (tmp >= 0 ? tmp : 0); \
279 tmp = dB - sB; dB = (tmp >= 0 ? tmp : 0); \
280 tmp = dA - sA; dA = (tmp >= 0 ? tmp : 0);
282 #define BLEND_RGBA_MULT(sR, sG, sB, sA, dR, dG, dB, dA) \
283 dR = (dR && sR) ? (dR * sR) >> 8 : 0; \
284 dG = (dG && sG) ? (dG * sG) >> 8 : 0; \
285 dB = (dB && sB) ? (dB * sB) >> 8 : 0; \
286 dA = (dA && sA) ? (dA * sA) >> 8 : 0;
288 #define BLEND_RGBA_MIN(sR, sG, sB, sA, dR, dG, dB, dA) \
289 if(sR < dR) { dR = sR; } \
290 if(sG < dG) { dG = sG; } \
291 if(sB < dB) { dB = sB; } \
292 if(sA < dA) { dA = sA; }
294 #define BLEND_RGBA_MAX(sR, sG, sB, sA, dR, dG, dB, dA) \
295 if(sR > dR) { dR = sR; } \
296 if(sG > dG) { dG = sG; } \
297 if(sB > dB) { dB = sB; } \
298 if(sA > dA) { dA = sA; }
311 /* Choose an alpha blend equation. If the sign is preserved on a right shift
312 * then use a specialized, faster, equation. Otherwise a more general form,
313 * where all additions are done before the shift, is needed.
316 #define ALPHA_BLEND_COMP(sC, dC, sA) ((((sC - dC) * sA + sC) >> 8) + dC)
318 #define ALPHA_BLEND_COMP(sC, dC, sA) (((dC << 8) + (sC - dC) * sA + sC) >> 8)
321 #define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \
325 dR = ALPHA_BLEND_COMP(sR, dR, sA); \
326 dG = ALPHA_BLEND_COMP(sG, dG, sA); \
327 dB = ALPHA_BLEND_COMP(sB, dB, sA); \
328 dA = sA + dA - ((sA * dA) / 255); \
339 #define ALPHA_BLEND_PREMULTIPLIED_COMP(sC, dC, sA) (sC + dC - ((dC + 1) * sA >> 8))
341 #define ALPHA_BLEND_PREMULTIPLIED(tmp, sR, sG, sB, sA, dR, dG, dB, dA) \
343 dR = ALPHA_BLEND_PREMULTIPLIED_COMP(sR, dR, sA); \
344 dG = ALPHA_BLEND_PREMULTIPLIED_COMP(sG, dG, sA); \
345 dB = ALPHA_BLEND_PREMULTIPLIED_COMP(sB, dB, sA); \
346 dA = ALPHA_BLEND_PREMULTIPLIED_COMP(sA, dA, sA); \
350 #define ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB, dA) \
353 if(dA && sA < 255){ \
354 int dContrib = dA*(255 - sA)/255; \
355 dA = sA+dA - ((sA*dA)/255); \
356 dR = (dR*dContrib + sR*sA)/dA; \
357 dG = (dG*dContrib + sG*sA)/dA; \
358 dB = (dB*dContrib + sB*sA)/dA; \
370 surface_fill_blend (SDL_Surface *surface, SDL_Rect *rect, Uint32 color,
374 surface_respect_clip_rect (SDL_Surface *surface, SDL_Rect *rect);
377 pygame_AlphaBlit (SDL_Surface * src, SDL_Rect * srcrect,
378 SDL_Surface * dst, SDL_Rect * dstrect, int the_args);
381 pygame_Blit (SDL_Surface * src, SDL_Rect * srcrect,
382 SDL_Surface * dst, SDL_Rect * dstrect, int the_args);
384 #endif /* SURFACE_H */