3 SDL_gfxPrimitives - Graphics primitives for SDL surfaces
16 #include "sdl_gfxprimitives.h"
17 #include "sdl_gfxprimitives_font.h"
19 /* -===================- */
21 /* Define this flag to use surface blits for alpha blended drawing. */
22 /* This is usually slower that direct surface calculations. */
24 #undef SURFACE_ALPHA_PIXEL
26 /* ----- Defines for pixel clipping tests */
28 #define clip_xmin(surface) surface->clip_rect.x
29 #define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
30 #define clip_ymin(surface) surface->clip_rect.y
31 #define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
33 /* ----- Pixel - fast, no blending, no locking, clipping */
35 int fastPixelColorNolock(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
)
41 * Honor clipping setup at pixel level
43 if ((x
>= clip_xmin(dst
)) && (x
<= clip_xmax(dst
)) && (y
>= clip_ymin(dst
)) && (y
<= clip_ymax(dst
))) {
46 * Get destination format
48 bpp
= dst
->format
->BytesPerPixel
;
49 p
= (Uint8
*) dst
->pixels
+ y
* dst
->pitch
+ x
* bpp
;
55 *(Uint16
*) p
= color
;
58 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
59 p
[0] = (color
>> 16) & 0xff;
60 p
[1] = (color
>> 8) & 0xff;
64 p
[1] = (color
>> 8) & 0xff;
65 p
[2] = (color
>> 16) & 0xff;
69 *(Uint32
*) p
= color
;
79 /* ----- Pixel - fast, no blending, no locking, no clipping */
81 /* (faster but dangerous, make sure we stay in surface bounds) */
83 int fastPixelColorNolockNoclip(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
)
89 * Get destination format
91 bpp
= dst
->format
->BytesPerPixel
;
92 p
= (Uint8
*) dst
->pixels
+ y
* dst
->pitch
+ x
* bpp
;
98 *(Uint16
*) p
= color
;
101 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
102 p
[0] = (color
>> 16) & 0xff;
103 p
[1] = (color
>> 8) & 0xff;
107 p
[1] = (color
>> 8) & 0xff;
108 p
[2] = (color
>> 16) & 0xff;
112 *(Uint32
*) p
= color
;
119 /* ----- Pixel - fast, no blending, locking, clipping */
121 int fastPixelColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
)
128 if (SDL_MUSTLOCK(dst
)) {
129 if (SDL_LockSurface(dst
) < 0) {
134 result
= fastPixelColorNolock(dst
, x
, y
, color
);
139 if (SDL_MUSTLOCK(dst
)) {
140 SDL_UnlockSurface(dst
);
146 /* ----- Pixel - fast, no blending, locking, RGB input */
148 int fastPixelRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
155 color
= SDL_MapRGBA(dst
->format
, r
, g
, b
, a
);
160 return (fastPixelColor(dst
, x
, y
, color
));
164 /* ----- Pixel - fast, no blending, no locking RGB input */
166 int fastPixelRGBANolock(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
173 color
= SDL_MapRGBA(dst
->format
, r
, g
, b
, a
);
178 return (fastPixelColorNolock(dst
, x
, y
, color
));
181 #ifdef SURFACE_ALPHA_PIXEL
183 /* ----- Pixel - using single pixel blit with blending enabled if a<255 */
185 /* Old, slower routine - normally disabled */
187 static SDL_Surface
*gfxPrimitivesSinglePixel
= NULL
;
189 int pixelColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
)
196 * Setup source rectangle for pixel
204 * Setup destination rectangle for pixel
212 * Create single pixel in 32bit RGBA format
214 if (gfxPrimitivesSinglePixel
== NULL
) {
215 gfxPrimitivesSinglePixel
=
216 SDL_CreateRGBSurface(SDL_SWSURFACE
| SDL_HWSURFACE
| SDL_SRCALPHA
, 1, 1,
217 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
221 * Draw color into pixel
223 SDL_FillRect(gfxPrimitivesSinglePixel
, &srect
, color
);
226 * Draw pixel onto destination surface
228 result
= SDL_BlitSurface(gfxPrimitivesSinglePixel
, &srect
, dst
, &drect
);
235 /* PutPixel routine with alpha blending, input color in destination format */
237 /* New, faster routine - default blending pixel */
239 int _putPixelAlpha(SDL_Surface
* surface
, Sint16 x
, Sint16 y
, Uint32 color
, Uint8 alpha
)
241 Uint32 Rmask
= surface
->format
->Rmask
, Gmask
=
242 surface
->format
->Gmask
, Bmask
= surface
->format
->Bmask
, Amask
= surface
->format
->Amask
;
243 Uint32 R
, G
, B
, A
= 0;
245 if (x
>= clip_xmin(surface
) && x
<= clip_xmax(surface
)
246 && y
>= clip_ymin(surface
) && y
<= clip_ymax(surface
)) {
248 switch (surface
->format
->BytesPerPixel
) {
249 case 1:{ /* Assuming 8-bpp */
251 *((Uint8
*) surface
->pixels
+ y
* surface
->pitch
+ x
) = color
;
253 Uint8
*pixel
= (Uint8
*) surface
->pixels
+ y
* surface
->pitch
+ x
;
255 Uint8 dR
= surface
->format
->palette
->colors
[*pixel
].r
;
256 Uint8 dG
= surface
->format
->palette
->colors
[*pixel
].g
;
257 Uint8 dB
= surface
->format
->palette
->colors
[*pixel
].b
;
258 Uint8 sR
= surface
->format
->palette
->colors
[color
].r
;
259 Uint8 sG
= surface
->format
->palette
->colors
[color
].g
;
260 Uint8 sB
= surface
->format
->palette
->colors
[color
].b
;
262 dR
= dR
+ ((sR
- dR
) * alpha
>> 8);
263 dG
= dG
+ ((sG
- dG
) * alpha
>> 8);
264 dB
= dB
+ ((sB
- dB
) * alpha
>> 8);
266 *pixel
= SDL_MapRGB(surface
->format
, dR
, dG
, dB
);
271 case 2:{ /* Probably 15-bpp or 16-bpp */
273 *((Uint16
*) surface
->pixels
+ y
* surface
->pitch
/ 2 + x
) = color
;
275 Uint16
*pixel
= (Uint16
*) surface
->pixels
+ y
* surface
->pitch
/ 2 + x
;
278 R
= ((dc
& Rmask
) + (((color
& Rmask
) - (dc
& Rmask
)) * alpha
>> 8)) & Rmask
;
279 G
= ((dc
& Gmask
) + (((color
& Gmask
) - (dc
& Gmask
)) * alpha
>> 8)) & Gmask
;
280 B
= ((dc
& Bmask
) + (((color
& Bmask
) - (dc
& Bmask
)) * alpha
>> 8)) & Bmask
;
282 A
= ((dc
& Amask
) + (((color
& Amask
) - (dc
& Amask
)) * alpha
>> 8)) & Amask
;
284 *pixel
= R
| G
| B
| A
;
289 case 3:{ /* Slow 24-bpp mode, usually not used */
290 Uint8
*pix
= (Uint8
*) surface
->pixels
+ y
* surface
->pitch
+ x
* 3;
291 Uint8 rshift8
= surface
->format
->Rshift
/ 8;
292 Uint8 gshift8
= surface
->format
->Gshift
/ 8;
293 Uint8 bshift8
= surface
->format
->Bshift
/ 8;
294 Uint8 ashift8
= surface
->format
->Ashift
/ 8;
298 *(pix
+ rshift8
) = color
>> surface
->format
->Rshift
;
299 *(pix
+ gshift8
) = color
>> surface
->format
->Gshift
;
300 *(pix
+ bshift8
) = color
>> surface
->format
->Bshift
;
301 *(pix
+ ashift8
) = color
>> surface
->format
->Ashift
;
303 Uint8 dR
, dG
, dB
, dA
= 0;
304 Uint8 sR
, sG
, sB
, sA
= 0;
306 pix
= (Uint8
*) surface
->pixels
+ y
* surface
->pitch
+ x
* 3;
308 dR
= *((pix
) + rshift8
);
309 dG
= *((pix
) + gshift8
);
310 dB
= *((pix
) + bshift8
);
311 dA
= *((pix
) + ashift8
);
313 sR
= (color
>> surface
->format
->Rshift
) & 0xff;
314 sG
= (color
>> surface
->format
->Gshift
) & 0xff;
315 sB
= (color
>> surface
->format
->Bshift
) & 0xff;
316 sA
= (color
>> surface
->format
->Ashift
) & 0xff;
318 dR
= dR
+ ((sR
- dR
) * alpha
>> 8);
319 dG
= dG
+ ((sG
- dG
) * alpha
>> 8);
320 dB
= dB
+ ((sB
- dB
) * alpha
>> 8);
321 dA
= dA
+ ((sA
- dA
) * alpha
>> 8);
323 *((pix
) + rshift8
) = dR
;
324 *((pix
) + gshift8
) = dG
;
325 *((pix
) + bshift8
) = dB
;
326 *((pix
) + ashift8
) = dA
;
331 case 4:{ /* Probably 32-bpp */
333 *((Uint32
*) surface
->pixels
+ y
* surface
->pitch
/ 4 + x
) = color
;
335 Uint32
*pixel
= (Uint32
*) surface
->pixels
+ y
* surface
->pitch
/ 4 + x
;
338 R
= ((dc
& Rmask
) + (((color
& Rmask
) - (dc
& Rmask
)) * alpha
>> 8)) & Rmask
;
339 G
= ((dc
& Gmask
) + (((color
& Gmask
) - (dc
& Gmask
)) * alpha
>> 8)) & Gmask
;
340 B
= ((dc
& Bmask
) + (((color
& Bmask
) - (dc
& Bmask
)) * alpha
>> 8)) & Bmask
;
342 A
= ((dc
& Amask
) + (((color
& Amask
) - (dc
& Amask
)) * alpha
>> 8)) & Amask
;
344 *pixel
= R
| G
| B
| A
;
354 /* ----- Pixel - pixel draw with blending enabled if a<255 */
356 int pixelColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
)
365 if (SDL_MUSTLOCK(dst
)) {
366 if (SDL_LockSurface(dst
) < 0) {
374 alpha
= color
& 0x000000ff;
376 SDL_MapRGBA(dst
->format
, (color
& 0xff000000) >> 24,
377 (color
& 0x00ff0000) >> 16, (color
& 0x0000ff00) >> 8, alpha
);
382 result
= _putPixelAlpha(dst
, x
, y
, mcolor
, alpha
);
387 if (SDL_MUSTLOCK(dst
)) {
388 SDL_UnlockSurface(dst
);
394 int pixelColorNolock(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
)
403 alpha
= color
& 0x000000ff;
405 SDL_MapRGBA(dst
->format
, (color
& 0xff000000) >> 24,
406 (color
& 0x00ff0000) >> 16, (color
& 0x0000ff00) >> 8, alpha
);
411 result
= _putPixelAlpha(dst
, x
, y
, mcolor
, alpha
);
417 /* Filled rectangle with alpha blending, color in destination format */
419 int _filledRectAlpha(SDL_Surface
* surface
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint32 color
, Uint8 alpha
)
421 Uint32 Rmask
= surface
->format
->Rmask
, Gmask
=
422 surface
->format
->Gmask
, Bmask
= surface
->format
->Bmask
, Amask
= surface
->format
->Amask
;
423 Uint32 R
, G
, B
, A
= 0;
426 switch (surface
->format
->BytesPerPixel
) {
427 case 1:{ /* Assuming 8-bpp */
431 Uint8 sR
= surface
->format
->palette
->colors
[color
].r
;
432 Uint8 sG
= surface
->format
->palette
->colors
[color
].g
;
433 Uint8 sB
= surface
->format
->palette
->colors
[color
].b
;
435 for (y
= y1
; y
<= y2
; y
++) {
436 row
= (Uint8
*) surface
->pixels
+ y
* surface
->pitch
;
437 for (x
= x1
; x
<= x2
; x
++) {
440 dR
= surface
->format
->palette
->colors
[*pixel
].r
;
441 dG
= surface
->format
->palette
->colors
[*pixel
].g
;
442 dB
= surface
->format
->palette
->colors
[*pixel
].b
;
444 dR
= dR
+ ((sR
- dR
) * alpha
>> 8);
445 dG
= dG
+ ((sG
- dG
) * alpha
>> 8);
446 dB
= dB
+ ((sB
- dB
) * alpha
>> 8);
448 *pixel
= SDL_MapRGB(surface
->format
, dR
, dG
, dB
);
454 case 2:{ /* Probably 15-bpp or 16-bpp */
456 Uint32 dR
= (color
& Rmask
), dG
= (color
& Gmask
), dB
= (color
& Bmask
), dA
= (color
& Amask
);
458 for (y
= y1
; y
<= y2
; y
++) {
459 row
= (Uint16
*) surface
->pixels
+ y
* surface
->pitch
/ 2;
460 for (x
= x1
; x
<= x2
; x
++) {
463 R
= ((*pixel
& Rmask
) + ((dR
- (*pixel
& Rmask
)) * alpha
>> 8)) & Rmask
;
464 G
= ((*pixel
& Gmask
) + ((dG
- (*pixel
& Gmask
)) * alpha
>> 8)) & Gmask
;
465 B
= ((*pixel
& Bmask
) + ((dB
- (*pixel
& Bmask
)) * alpha
>> 8)) & Bmask
;
467 A
= ((*pixel
& Amask
) + ((dA
- (*pixel
& Amask
)) * alpha
>> 8)) & Amask
;
469 *pixel
= R
| G
| B
| A
;
475 case 3:{ /* Slow 24-bpp mode, usually not used */
477 Uint8 dR
, dG
, dB
, dA
;
478 Uint8 rshift8
= surface
->format
->Rshift
/ 8;
479 Uint8 gshift8
= surface
->format
->Gshift
/ 8;
480 Uint8 bshift8
= surface
->format
->Bshift
/ 8;
481 Uint8 ashift8
= surface
->format
->Ashift
/ 8;
483 Uint8 sR
= (color
>> surface
->format
->Rshift
) & 0xff;
484 Uint8 sG
= (color
>> surface
->format
->Gshift
) & 0xff;
485 Uint8 sB
= (color
>> surface
->format
->Bshift
) & 0xff;
486 Uint8 sA
= (color
>> surface
->format
->Ashift
) & 0xff;
488 for (y
= y1
; y
<= y2
; y
++) {
489 row
= (Uint8
*) surface
->pixels
+ y
* surface
->pitch
;
490 for (x
= x1
; x
<= x2
; x
++) {
493 dR
= *((pix
) + rshift8
);
494 dG
= *((pix
) + gshift8
);
495 dB
= *((pix
) + bshift8
);
496 dA
= *((pix
) + ashift8
);
498 dR
= dR
+ ((sR
- dR
) * alpha
>> 8);
499 dG
= dG
+ ((sG
- dG
) * alpha
>> 8);
500 dB
= dB
+ ((sB
- dB
) * alpha
>> 8);
501 dA
= dA
+ ((sA
- dA
) * alpha
>> 8);
503 *((pix
) + rshift8
) = dR
;
504 *((pix
) + gshift8
) = dG
;
505 *((pix
) + bshift8
) = dB
;
506 *((pix
) + ashift8
) = dA
;
513 case 4:{ /* Probably 32-bpp */
515 Uint32 dR
= (color
& Rmask
), dG
= (color
& Gmask
), dB
= (color
& Bmask
), dA
= (color
& Amask
);
517 for (y
= y1
; y
<= y2
; y
++) {
518 row
= (Uint32
*) surface
->pixels
+ y
* surface
->pitch
/ 4;
519 for (x
= x1
; x
<= x2
; x
++) {
522 R
= ((*pixel
& Rmask
) + ((dR
- (*pixel
& Rmask
)) * alpha
>> 8)) & Rmask
;
523 G
= ((*pixel
& Gmask
) + ((dG
- (*pixel
& Gmask
)) * alpha
>> 8)) & Gmask
;
524 B
= ((*pixel
& Bmask
) + ((dB
- (*pixel
& Bmask
)) * alpha
>> 8)) & Bmask
;
526 A
= ((*pixel
& Amask
) + ((dA
- (*pixel
& Amask
)) * alpha
>> 8)) & Amask
;
528 *pixel
= R
| G
| B
| A
;
538 /* Draw rectangle with alpha enabled from RGBA color. */
540 int filledRectAlpha(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint32 color
)
549 if (SDL_MUSTLOCK(dst
)) {
550 if (SDL_LockSurface(dst
) < 0) {
558 alpha
= color
& 0x000000ff;
560 SDL_MapRGBA(dst
->format
, (color
& 0xff000000) >> 24,
561 (color
& 0x00ff0000) >> 16, (color
& 0x0000ff00) >> 8, alpha
);
566 result
= _filledRectAlpha(dst
, x1
, y1
, x2
, y2
, mcolor
, alpha
);
571 if (SDL_MUSTLOCK(dst
)) {
572 SDL_UnlockSurface(dst
);
578 /* Draw horizontal line with alpha enabled from RGBA color */
580 int HLineAlpha(SDL_Surface
* dst
, Sint16 x1
, Sint16 x2
, Sint16 y
, Uint32 color
)
582 return (filledRectAlpha(dst
, x1
, y
, x2
, y
, color
));
586 /* Draw vertical line with alpha enabled from RGBA color */
588 int VLineAlpha(SDL_Surface
* dst
, Sint16 x
, Sint16 y1
, Sint16 y2
, Uint32 color
)
590 return (filledRectAlpha(dst
, x
, y1
, x
, y2
, color
));
596 /* Pixel - using alpha weight on color for AA-drawing */
598 int pixelColorWeight(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
, Uint32 weight
)
605 a
= (color
& (Uint32
) 0x000000ff);
608 * Modify Alpha by weight
610 a
= ((a
* weight
) >> 8);
612 return (pixelColor(dst
, x
, y
, (color
& (Uint32
) 0xffffff00) | (Uint32
) a
));
615 /* Pixel - using alpha weight on color for AA-drawing - no locking */
617 int pixelColorWeightNolock(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint32 color
, Uint32 weight
)
624 a
= (color
& (Uint32
) 0x000000ff);
627 * Modify Alpha by weight
629 a
= ((a
* weight
) >> 8);
631 return (pixelColorNolock(dst
, x
, y
, (color
& (Uint32
) 0xffffff00) | (Uint32
) a
));
634 int pixelRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
643 * No alpha blending required
648 color
= SDL_MapRGBA(dst
->format
, r
, g
, b
, a
);
652 return (fastPixelColor(dst
, x
, y
, color
));
655 * Alpha blending required
660 return (pixelColor(dst
, x
, y
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
664 /* ----- Horizontal line */
666 #ifdef SURFACE_ALPHA_PIXEL
667 static SDL_Surface
*gfxPrimitivesHline
= NULL
;
670 int hlineColor(SDL_Surface
* dst
, Sint16 x1
, Sint16 x2
, Sint16 y
, Uint32 color
)
672 Sint16 left
, right
, top
, bottom
;
673 Uint8
*pixel
, *pixellast
;
681 #ifdef SURFACE_ALPHA_PIXEL
688 * Get clipping boundary
690 left
= dst
->clip_rect
.x
;
691 right
= dst
->clip_rect
.x
+ dst
->clip_rect
.w
- 1;
692 top
= dst
->clip_rect
.y
;
693 bottom
= dst
->clip_rect
.y
+ dst
->clip_rect
.h
- 1;
696 * Swap x1, x2 if required
707 if ((x1
> right
) || (x2
< left
) || (y
< top
) || (y
> bottom
)) {
727 * Sanity check on width
736 if ((color
& 255) == 255) {
739 * No alpha-blending required
745 colorptr
= (Uint8
*) & color
;
746 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
747 color
= SDL_MapRGBA(dst
->format
, colorptr
[0], colorptr
[1], colorptr
[2], colorptr
[3]);
749 color
= SDL_MapRGBA(dst
->format
, colorptr
[3], colorptr
[2], colorptr
[1], colorptr
[0]);
755 SDL_LockSurface(dst
);
758 * More variable setup
761 pixx
= dst
->format
->BytesPerPixel
;
763 pixel
= ((Uint8
*) dst
->pixels
) + pixx
* (int) x1
+ pixy
* (int) y
;
768 switch (dst
->format
->BytesPerPixel
) {
770 memset(pixel
, color
, dx
);
773 pixellast
= pixel
+ dx
+ dx
;
774 for (; pixel
<= pixellast
; pixel
+= pixx
) {
775 *(Uint16
*) pixel
= color
;
779 pixellast
= pixel
+ dx
+ dx
+ dx
;
780 for (; pixel
<= pixellast
; pixel
+= pixx
) {
781 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
782 pixel
[0] = (color
>> 16) & 0xff;
783 pixel
[1] = (color
>> 8) & 0xff;
784 pixel
[2] = color
& 0xff;
786 pixel
[0] = color
& 0xff;
787 pixel
[1] = (color
>> 8) & 0xff;
788 pixel
[2] = (color
>> 16) & 0xff;
792 default: /* case 4 */
794 pixellast
= pixel
+ dx
+ dx
;
795 for (; pixel
<= pixellast
; pixel
+= pixx
) {
796 *(Uint32
*) pixel
= color
;
804 SDL_UnlockSurface(dst
);
814 * Alpha blending blit
817 #ifdef SURFACE_ALPHA_PIXEL
820 * Adjust width for Rect setup
825 * Setup source rectangle for pixel
833 * Setup rectangle for destination line
841 * Maybe deallocate existing surface if size is too small
843 if ((gfxPrimitivesHline
!= NULL
) && (gfxPrimitivesHline
->w
< w
)) {
844 SDL_FreeSurface(gfxPrimitivesHline
);
845 gfxPrimitivesHline
= NULL
;
849 * Create horizontal line surface in destination format if necessary
851 if (gfxPrimitivesHline
== NULL
) {
853 SDL_CreateRGBSurface(SDL_SWSURFACE
| SDL_HWSURFACE
| SDL_SRCALPHA
, w
,
854 1, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
860 a
= (color
& (Uint32
) 0x000000ff);
863 * Toggle alpha blending if necessary, reset otherwise
866 SDL_SetAlpha(gfxPrimitivesHline
, SDL_SRCALPHA
, 255);
868 SDL_SetAlpha(gfxPrimitivesHline
, 0, 255);
872 * Draw color into pixel
874 SDL_FillRect(gfxPrimitivesHline
, &srect
, color
);
877 * Draw pixel onto destination surface
879 result
= SDL_BlitSurface(gfxPrimitivesHline
, &srect
, dst
, &drect
);
883 result
= HLineAlpha(dst
, x1
, x1
+ w
, y
, color
);
892 int hlineRGBA(SDL_Surface
* dst
, Sint16 x1
, Sint16 x2
, Sint16 y
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
897 return (hlineColor(dst
, x1
, x2
, y
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
900 /* ----- Vertical line */
902 #ifdef SURFACE_ALPHA_PIXEL
903 static SDL_Surface
*gfxPrimitivesVline
= NULL
;
906 int vlineColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y1
, Sint16 y2
, Uint32 color
)
908 Sint16 left
, right
, top
, bottom
;
909 Uint8
*pixel
, *pixellast
;
917 #ifdef SURFACE_ALPHA_PIXEL
924 * Get clipping boundary
926 left
= dst
->clip_rect
.x
;
927 right
= dst
->clip_rect
.x
+ dst
->clip_rect
.w
- 1;
928 top
= dst
->clip_rect
.y
;
929 bottom
= dst
->clip_rect
.y
+ dst
->clip_rect
.h
- 1;
932 * Swap y1, y2 if required
943 if ((y2
< top
) || (y1
> bottom
) || (x
< left
) || (x
> right
)) {
963 * Sanity check on height
972 if ((color
& 255) == 255) {
975 * No alpha-blending required
981 colorptr
= (Uint8
*) & color
;
982 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
983 color
= SDL_MapRGBA(dst
->format
, colorptr
[0], colorptr
[1], colorptr
[2], colorptr
[3]);
985 color
= SDL_MapRGBA(dst
->format
, colorptr
[3], colorptr
[2], colorptr
[1], colorptr
[0]);
991 SDL_LockSurface(dst
);
994 * More variable setup
997 pixx
= dst
->format
->BytesPerPixel
;
999 pixel
= ((Uint8
*) dst
->pixels
) + pixx
* (int) x
+ pixy
* (int) y1
;
1000 pixellast
= pixel
+ pixy
* dy
;
1005 switch (dst
->format
->BytesPerPixel
) {
1007 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1008 *(Uint8
*) pixel
= color
;
1012 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1013 *(Uint16
*) pixel
= color
;
1017 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1018 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
1019 pixel
[0] = (color
>> 16) & 0xff;
1020 pixel
[1] = (color
>> 8) & 0xff;
1021 pixel
[2] = color
& 0xff;
1023 pixel
[0] = color
& 0xff;
1024 pixel
[1] = (color
>> 8) & 0xff;
1025 pixel
[2] = (color
>> 16) & 0xff;
1029 default: /* case 4 */
1030 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1031 *(Uint32
*) pixel
= color
;
1039 SDL_UnlockSurface(dst
);
1049 * Alpha blending blit
1052 #ifdef SURFACE_ALPHA_PIXEL
1055 * Adjust height for Rect setup
1060 * Setup source rectangle for pixel
1068 * Setup rectangle for line
1076 * Maybe deallocate existing surface if size is too small
1078 if ((gfxPrimitivesVline
!= NULL
) && (gfxPrimitivesVline
->h
< h
)) {
1079 SDL_FreeSurface(gfxPrimitivesVline
);
1080 gfxPrimitivesVline
= NULL
;
1084 * Create horizontal line surface in destination format if necessary
1086 if (gfxPrimitivesVline
== NULL
) {
1087 gfxPrimitivesVline
=
1088 SDL_CreateRGBSurface(SDL_SWSURFACE
| SDL_HWSURFACE
| SDL_SRCALPHA
, 1,
1089 h
, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
1095 a
= (color
& (Uint32
) 0x000000ff);
1098 * Toggle alpha blending if necessary, reset otherwise
1101 SDL_SetAlpha(gfxPrimitivesVline
, SDL_SRCALPHA
, 255);
1103 SDL_SetAlpha(gfxPrimitivesVline
, 0, 255);
1107 * Draw color into pixel
1109 SDL_FillRect(gfxPrimitivesVline
, &srect
, color
);
1112 * Draw Vline onto destination surface
1114 result
= SDL_BlitSurface(gfxPrimitivesVline
, &srect
, dst
, &drect
);
1118 result
= VLineAlpha(dst
, x
, y1
, y1
+ h
, color
);
1127 int vlineRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y1
, Sint16 y2
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
1132 return (vlineColor(dst
, x
, y1
, y2
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
1135 /* ----- Rectangle */
1137 int rectangleColor(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint32 color
)
1140 Sint16 w
, h
, xtmp
, ytmp
;
1144 * Swap x1, x2 if required
1153 * Swap y1, y2 if required
1162 * Calculate width&height
1170 if ((w
< 0) || (h
< 0)) {
1175 * Test for special cases of straight lines or single point
1179 return (pixelColor(dst
, x1
, y1
, color
));
1181 return (vlineColor(dst
, x1
, y1
, y2
, color
));
1185 return (hlineColor(dst
, x1
, x2
, y1
, color
));
1193 result
|= vlineColor(dst
, x1
, y1
, y2
, color
);
1194 result
|= vlineColor(dst
, x2
, y1
, y2
, color
);
1195 result
|= hlineColor(dst
, x1
, x2
, y1
, color
);
1196 result
|= hlineColor(dst
, x1
, x2
, y2
, color
);
1202 int rectangleRGBA(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
1207 return (rectangleColor
1208 (dst
, x1
, y1
, x2
, y2
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
1211 /* --------- Clipping routines for box/line */
1213 /* Clipping based heavily on code from */
1215 /* http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c */
1217 #define CLIP_LEFT_EDGE 0x1
1218 #define CLIP_RIGHT_EDGE 0x2
1219 #define CLIP_BOTTOM_EDGE 0x4
1220 #define CLIP_TOP_EDGE 0x8
1221 #define CLIP_INSIDE(a) (!a)
1222 #define CLIP_REJECT(a,b) (a&b)
1223 #define CLIP_ACCEPT(a,b) (!(a|b))
1225 static int clipEncode(Sint16 x
, Sint16 y
, Sint16 left
, Sint16 top
, Sint16 right
, Sint16 bottom
)
1230 code
|= CLIP_LEFT_EDGE
;
1231 } else if (x
> right
) {
1232 code
|= CLIP_RIGHT_EDGE
;
1235 code
|= CLIP_TOP_EDGE
;
1236 } else if (y
> bottom
) {
1237 code
|= CLIP_BOTTOM_EDGE
;
1242 static int clipLine(SDL_Surface
* dst
, Sint16
* x1
, Sint16
* y1
, Sint16
* x2
, Sint16
* y2
)
1244 Sint16 left
, right
, top
, bottom
;
1251 * Get clipping boundary
1253 left
= dst
->clip_rect
.x
;
1254 right
= dst
->clip_rect
.x
+ dst
->clip_rect
.w
- 1;
1255 top
= dst
->clip_rect
.y
;
1256 bottom
= dst
->clip_rect
.y
+ dst
->clip_rect
.h
- 1;
1259 code1
= clipEncode(*x1
, *y1
, left
, top
, right
, bottom
);
1260 code2
= clipEncode(*x2
, *y2
, left
, top
, right
, bottom
);
1261 if (CLIP_ACCEPT(code1
, code2
)) {
1264 } else if (CLIP_REJECT(code1
, code2
))
1267 if (CLIP_INSIDE(code1
)) {
1279 m
= (*y2
- *y1
) / (float) (*x2
- *x1
);
1283 if (code1
& CLIP_LEFT_EDGE
) {
1284 *y1
+= (Sint16
) ((left
- *x1
) * m
);
1286 } else if (code1
& CLIP_RIGHT_EDGE
) {
1287 *y1
+= (Sint16
) ((right
- *x1
) * m
);
1289 } else if (code1
& CLIP_BOTTOM_EDGE
) {
1291 *x1
+= (Sint16
) ((bottom
- *y1
) / m
);
1294 } else if (code1
& CLIP_TOP_EDGE
) {
1296 *x1
+= (Sint16
) ((top
- *y1
) / m
);
1306 /* ----- Filled rectangle (Box) */
1308 #ifdef SURFACE_ALPHA_PIXEL
1309 static SDL_Surface
*gfxPrimitivesBox
= NULL
;
1312 int boxColor(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint32 color
)
1314 Uint8
*pixel
, *pixellast
;
1322 #ifdef SURFACE_ALPHA_PIXEL
1329 * Clip diagonal and test if we have to draw
1331 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
1336 * Test for special cases of straight lines or single point
1340 return (vlineColor(dst
, x1
, y1
, y2
, color
));
1341 } else if (y1
> y2
) {
1342 return (vlineColor(dst
, x1
, y2
, y1
, color
));
1344 return (pixelColor(dst
, x1
, y1
, color
));
1349 return (hlineColor(dst
, x1
, x2
, y1
, color
));
1350 } else if (x1
> x2
) {
1351 return (hlineColor(dst
, x2
, x1
, y1
, color
));
1370 * Calculate width&height
1378 if ((color
& 255) == 255) {
1381 * No alpha-blending required
1387 colorptr
= (Uint8
*) & color
;
1388 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
1389 color
= SDL_MapRGBA(dst
->format
, colorptr
[0], colorptr
[1], colorptr
[2], colorptr
[3]);
1391 color
= SDL_MapRGBA(dst
->format
, colorptr
[3], colorptr
[2], colorptr
[1], colorptr
[0]);
1397 SDL_LockSurface(dst
);
1400 * More variable setup
1404 pixx
= dst
->format
->BytesPerPixel
;
1406 pixel
= ((Uint8
*) dst
->pixels
) + pixx
* (int) x1
+ pixy
* (int) y1
;
1407 pixellast
= pixel
+ pixx
* dx
+ pixy
* dy
;
1412 switch (dst
->format
->BytesPerPixel
) {
1414 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1415 memset(pixel
, (Uint8
) color
, dx
);
1419 pixy
-= (pixx
* dx
);
1420 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1421 for (x
= 0; x
< dx
; x
++) {
1422 *(Uint16
*) pixel
= color
;
1428 pixy
-= (pixx
* dx
);
1429 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1430 for (x
= 0; x
< dx
; x
++) {
1431 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
1432 pixel
[0] = (color
>> 16) & 0xff;
1433 pixel
[1] = (color
>> 8) & 0xff;
1434 pixel
[2] = color
& 0xff;
1436 pixel
[0] = color
& 0xff;
1437 pixel
[1] = (color
>> 8) & 0xff;
1438 pixel
[2] = (color
>> 16) & 0xff;
1444 default: /* case 4 */
1445 pixy
-= (pixx
* dx
);
1446 for (; pixel
<= pixellast
; pixel
+= pixy
) {
1447 for (x
= 0; x
< dx
; x
++) {
1448 *(Uint32
*) pixel
= color
;
1458 SDL_UnlockSurface(dst
);
1464 #ifdef SURFACE_ALPHA_PIXEL
1467 * Setup source rectangle for pixel
1475 * Setup rectangle for line
1483 * Maybe deallocate existing surface if size is too small
1485 if ((gfxPrimitivesBox
!= NULL
)
1486 && ((gfxPrimitivesBox
->w
< w
) || (gfxPrimitivesBox
->h
< h
))) {
1487 SDL_FreeSurface(gfxPrimitivesBox
);
1488 gfxPrimitivesBox
= NULL
;
1492 * Create box surface in destination format if necessary
1494 if (gfxPrimitivesBox
== NULL
) {
1496 SDL_CreateRGBSurface(SDL_SWSURFACE
| SDL_HWSURFACE
| SDL_SRCALPHA
, w
,
1497 h
, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
1503 a
= (color
& (Uint32
) 0x000000ff);
1506 * Toggle alpha blending if necessary, reset otherwise
1509 SDL_SetAlpha(gfxPrimitivesBox
, SDL_SRCALPHA
, 255);
1511 SDL_SetAlpha(gfxPrimitivesBox
, 0, 255);
1515 * Draw color into pixel
1517 SDL_FillRect(gfxPrimitivesBox
, &srect
, color
);
1520 * Draw pixel onto destination surface
1522 result
= SDL_BlitSurface(gfxPrimitivesBox
, &srect
, dst
, &drect
);
1526 result
= filledRectAlpha(dst
, x1
, y1
, x1
+ w
, y1
+ h
, color
);
1535 int boxRGBA(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
1540 return (boxColor(dst
, x1
, y1
, x2
, y2
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
1545 /* Non-alpha line drawing code adapted from routine */
1546 /* by Pete Shinners, pete@shinners.org */
1547 /* Originally from pygame, http://pygame.seul.org */
1549 #define ABS(a) (((a)<0) ? -(a) : (a))
1551 int lineColor(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint32 color
)
1563 * Clip line and test if we have to draw
1565 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
1570 * Test for special cases of straight lines or single point
1574 return (vlineColor(dst
, x1
, y1
, y2
, color
));
1575 } else if (y1
> y2
) {
1576 return (vlineColor(dst
, x1
, y2
, y1
, color
));
1578 return (pixelColor(dst
, x1
, y1
, color
));
1583 return (hlineColor(dst
, x1
, x2
, y1
, color
));
1584 } else if (x1
> x2
) {
1585 return (hlineColor(dst
, x2
, x1
, y1
, color
));
1594 sx
= (dx
>= 0) ? 1 : -1;
1595 sy
= (dy
>= 0) ? 1 : -1;
1598 if (SDL_MUSTLOCK(dst
)) {
1599 if (SDL_LockSurface(dst
) < 0) {
1605 * Check for alpha blending
1607 if ((color
& 255) == 255) {
1610 * No alpha blending - use fast pixel routines
1616 colorptr
= (Uint8
*) & color
;
1617 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
1618 color
= SDL_MapRGBA(dst
->format
, colorptr
[0], colorptr
[1], colorptr
[2], colorptr
[3]);
1620 color
= SDL_MapRGBA(dst
->format
, colorptr
[3], colorptr
[2], colorptr
[1], colorptr
[0]);
1624 * More variable setup
1628 pixx
= dst
->format
->BytesPerPixel
;
1630 pixel
= ((Uint8
*) dst
->pixels
) + pixx
* (int) x1
+ pixy
* (int) y1
;
1647 switch (dst
->format
->BytesPerPixel
) {
1649 for (; x
< dx
; x
++, pixel
+= pixx
) {
1659 for (; x
< dx
; x
++, pixel
+= pixx
) {
1660 *(Uint16
*) pixel
= color
;
1669 for (; x
< dx
; x
++, pixel
+= pixx
) {
1670 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
1671 pixel
[0] = (color
>> 16) & 0xff;
1672 pixel
[1] = (color
>> 8) & 0xff;
1673 pixel
[2] = color
& 0xff;
1675 pixel
[0] = color
& 0xff;
1676 pixel
[1] = (color
>> 8) & 0xff;
1677 pixel
[2] = (color
>> 16) & 0xff;
1686 default: /* case 4 */
1687 for (; x
< dx
; x
++, pixel
+= pixx
) {
1688 *(Uint32
*) pixel
= color
;
1701 * Alpha blending required - use single-pixel blits
1709 int d
= ay
- (ax
>> 1);
1712 pixelColorNolock (dst
, x
, y
, color
);
1713 if (d
> 0 || (d
== 0 && sx
== 1)) {
1721 int d
= ax
- (ay
>> 1);
1724 pixelColorNolock (dst
, x
, y
, color
);
1725 if (d
> 0 || ((d
== 0) && (sy
== 1))) {
1733 pixelColorNolock (dst
, x
, y
, color
);
1737 /* Unlock surface */
1738 if (SDL_MUSTLOCK(dst
)) {
1739 SDL_UnlockSurface(dst
);
1745 int lineRGBA(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
1750 return (lineColor(dst
, x1
, y1
, x2
, y2
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
1755 #define AAlevels 256
1760 This implementation of the Wu antialiasing code is based on Mike Abrash's
1761 DDJ article which was reprinted as Chapter 42 of his Graphics Programming
1762 Black Book, but has been optimized to work with SDL and utilizes 32-bit
1763 fixed-point arithmetic. (A. Schiffler).
1767 int aalineColorInt(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint32 color
, int draw_endpoint
)
1769 Sint32 xx0
, yy0
, xx1
, yy1
;
1771 Uint32 intshift
, erracc
, erradj
;
1772 Uint32 erracctmp
, wgt
, wgtcompmask
;
1773 int dx
, dy
, tmp
, xdir
, y0p1
, x0pxdir
;
1776 * Clip line and test if we have to draw
1778 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
1783 * Keep on working with 32bit numbers
1791 * Reorder points if required
1803 * Calculate distance
1809 * Adjust for negative dx and set xdir
1819 * Check for special cases
1825 return (vlineColor(dst
, x1
, y1
, y2
, color
));
1826 } else if (dy
== 0) {
1830 return (hlineColor(dst
, x1
, x2
, y1
, color
));
1831 } else if (dx
== dy
) {
1835 return (lineColor(dst
, x1
, y1
, x2
, y2
, color
));
1839 * Line is not horizontal, vertical or diagonal
1849 * # of bits by which to shift erracc to get intensity level
1851 intshift
= 32 - AAbits
;
1853 * Mask used to flip all bits in an intensity weighting
1855 wgtcompmask
= AAlevels
- 1;
1858 if (SDL_MUSTLOCK(dst
)) {
1859 if (SDL_LockSurface(dst
) < 0) {
1865 * Draw the initial pixel in the foreground color
1867 result
|= pixelColorNolock(dst
, x1
, y1
, color
);
1870 * x-major or y-major?
1875 * y-major. Calculate 16-bit fixed point fractional part of a pixel that
1876 * X advances every time Y advances 1 pixel, truncating the result so that
1877 * we won't overrun the endpoint along the X axis
1880 * Not-so-portable version: erradj = ((Uint64)dx << 32) / (Uint64)dy;
1882 erradj
= ((dx
<< 16) / dy
) << 16;
1885 * draw all pixels other than the first and last
1887 x0pxdir
= xx0
+ xdir
;
1891 if (erracc
<= erracctmp
) {
1893 * rollover in error accumulator, x coord advances
1898 yy0
++; /* y-major so always advance Y */
1901 * the AAbits most significant bits of erracc give us the intensity
1902 * weighting for this pixel, and the complement of the weighting for
1905 wgt
= (erracc
>> intshift
) & 255;
1906 result
|= pixelColorWeightNolock (dst
, xx0
, yy0
, color
, 255 - wgt
);
1907 result
|= pixelColorWeightNolock (dst
, x0pxdir
, yy0
, color
, wgt
);
1913 * x-major line. Calculate 16-bit fixed-point fractional part of a pixel
1914 * that Y advances each time X advances 1 pixel, truncating the result so
1915 * that we won't overrun the endpoint along the X axis.
1918 * Not-so-portable version: erradj = ((Uint64)dy << 32) / (Uint64)dx;
1920 erradj
= ((dy
<< 16) / dx
) << 16;
1923 * draw all pixels other than the first and last
1930 if (erracc
<= erracctmp
) {
1932 * Accumulator turned over, advance y
1937 xx0
+= xdir
; /* x-major so always advance X */
1939 * the AAbits most significant bits of erracc give us the intensity
1940 * weighting for this pixel, and the complement of the weighting for
1943 wgt
= (erracc
>> intshift
) & 255;
1944 result
|= pixelColorWeightNolock (dst
, xx0
, yy0
, color
, 255 - wgt
);
1945 result
|= pixelColorWeightNolock (dst
, xx0
, y0p1
, color
, wgt
);
1950 * Do we have to draw the endpoint
1952 if (draw_endpoint
) {
1954 * Draw final pixel, always exactly intersected by the line and doesn't
1955 * need to be weighted.
1957 result
|= pixelColorNolock (dst
, x2
, y2
, color
);
1960 /* Unlock surface */
1961 if (SDL_MUSTLOCK(dst
)) {
1962 SDL_UnlockSurface(dst
);
1968 int aalineColor(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint32 color
)
1970 return (aalineColorInt(dst
, x1
, y1
, x2
, y2
, color
, 1));
1973 int aalineRGBA(SDL_Surface
* dst
, Sint16 x1
, Sint16 y1
, Sint16 x2
, Sint16 y2
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
1975 return (aalineColorInt
1976 (dst
, x1
, y1
, x2
, y2
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
, 1));
1982 /* Note: Based on algorithm from sge library, modified by A. Schiffler */
1984 /* with multiple pixel-draw removal and other minor speedup changes. */
1986 int circleColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 r
, Uint32 color
)
1989 Sint16 x1
, y1
, x2
, y2
;
1992 Sint16 ocx
= (Sint16
) 0xffff;
1993 Sint16 ocy
= (Sint16
) 0xffff;
1996 Sint16 d_se
= -2 * r
+ 5;
1997 Sint16 xpcx
, xmcx
, xpcy
, xmcy
;
1998 Sint16 ypcy
, ymcy
, ypcx
, ymcx
;
2002 * Sanity check radius
2009 * Special case for r=0 - draw a point
2012 return (pixelColor(dst
, x
, y
, color
));
2016 * Test if bounding box of circle is visible
2022 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
2032 if (SDL_MUSTLOCK(dst
)) {
2033 if (SDL_LockSurface(dst
) < 0) {
2041 if ((color
& 255) == 255) {
2044 * No Alpha - direct memory writes
2050 colorptr
= (Uint8
*) & color
;
2051 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
2052 color
= SDL_MapRGBA(dst
->format
, colorptr
[0], colorptr
[1], colorptr
[2], colorptr
[3]);
2054 color
= SDL_MapRGBA(dst
->format
, colorptr
[3], colorptr
[2], colorptr
[1], colorptr
[0]);
2061 if ((ocy
!= cy
) || (ocx
!= cx
)) {
2067 result
|= fastPixelColorNolock(dst
, xmcx
, ypcy
, color
);
2068 result
|= fastPixelColorNolock(dst
, xpcx
, ypcy
, color
);
2069 result
|= fastPixelColorNolock(dst
, xmcx
, ymcy
, color
);
2070 result
|= fastPixelColorNolock(dst
, xpcx
, ymcy
, color
);
2072 result
|= fastPixelColorNolock(dst
, xmcx
, y
, color
);
2073 result
|= fastPixelColorNolock(dst
, xpcx
, y
, color
);
2081 result
|= fastPixelColorNolock(dst
, xmcy
, ypcx
, color
);
2082 result
|= fastPixelColorNolock(dst
, xpcy
, ypcx
, color
);
2083 result
|= fastPixelColorNolock(dst
, xmcy
, ymcx
, color
);
2084 result
|= fastPixelColorNolock(dst
, xpcy
, ymcx
, color
);
2086 result
|= fastPixelColorNolock(dst
, xmcy
, y
, color
);
2087 result
|= fastPixelColorNolock(dst
, xpcy
, y
, color
);
2110 SDL_UnlockSurface(dst
);
2115 * Using Alpha - blended pixel blits
2122 if ((ocy
!= cy
) || (ocx
!= cx
)) {
2128 result
|= pixelColorNolock (dst
, xmcx
, ypcy
, color
);
2129 result
|= pixelColorNolock (dst
, xpcx
, ypcy
, color
);
2130 result
|= pixelColorNolock (dst
, xmcx
, ymcy
, color
);
2131 result
|= pixelColorNolock (dst
, xpcx
, ymcy
, color
);
2133 result
|= pixelColorNolock (dst
, xmcx
, y
, color
);
2134 result
|= pixelColorNolock (dst
, xpcx
, y
, color
);
2142 result
|= pixelColorNolock (dst
, xmcy
, ypcx
, color
);
2143 result
|= pixelColorNolock (dst
, xpcy
, ypcx
, color
);
2144 result
|= pixelColorNolock (dst
, xmcy
, ymcx
, color
);
2145 result
|= pixelColorNolock (dst
, xpcy
, ymcx
, color
);
2147 result
|= pixelColorNolock (dst
, xmcy
, y
, color
);
2148 result
|= pixelColorNolock (dst
, xpcy
, y
, color
);
2170 /* Unlock surface */
2171 if (SDL_MUSTLOCK(dst
)) {
2172 SDL_UnlockSurface(dst
);
2178 int circleRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rad
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
2183 return (circleColor(dst
, x
, y
, rad
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
2186 /* ----- AA Circle */
2188 /* AA circle is based on AAellipse */
2190 int aacircleColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 r
, Uint32 color
)
2192 return (aaellipseColor(dst
, x
, y
, r
, r
, color
));
2195 int aacircleRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rad
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
2200 return (aaellipseColor
2201 (dst
, x
, y
, rad
, rad
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
2204 /* ----- Filled Circle */
2206 /* Note: Based on algorithm from sge library with multiple-hline draw removal */
2208 /* and other speedup changes. */
2210 int filledCircleColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 r
, Uint32 color
)
2213 Sint16 x1
, y1
, x2
, y2
;
2216 Sint16 ocx
= (Sint16
) 0xffff;
2217 Sint16 ocy
= (Sint16
) 0xffff;
2220 Sint16 d_se
= -2 * r
+ 5;
2221 Sint16 xpcx
, xmcx
, xpcy
, xmcy
;
2222 Sint16 ypcy
, ymcy
, ypcx
, ymcx
;
2225 * Sanity check radius
2232 * Special case for r=0 - draw a point
2235 return (pixelColor(dst
, x
, y
, color
));
2245 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
2262 result
|= hlineColor(dst
, xmcx
, xpcx
, ypcy
, color
);
2263 result
|= hlineColor(dst
, xmcx
, xpcx
, ymcy
, color
);
2265 result
|= hlineColor(dst
, xmcx
, xpcx
, y
, color
);
2274 result
|= hlineColor(dst
, xmcy
, xpcy
, ymcx
, color
);
2275 result
|= hlineColor(dst
, xmcy
, xpcy
, ypcx
, color
);
2277 result
|= hlineColor(dst
, xmcy
, xpcy
, y
, color
);
2301 int filledCircleRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rad
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
2306 return (filledCircleColor
2307 (dst
, x
, y
, rad
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
2313 /* Note: Based on algorithm from sge library with multiple-hline draw removal */
2315 /* and other speedup changes. */
2317 int ellipseColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rx
, Sint16 ry
, Uint32 color
)
2320 Sint16 x1
, y1
, x2
, y2
;
2324 int xmh
, xph
, ypk
, ymk
;
2325 int xmi
, xpi
, ymj
, ypj
;
2326 int xmj
, xpj
, ymi
, ypi
;
2327 int xmk
, xpk
, ymh
, yph
;
2331 * Sanity check radii
2333 if ((rx
< 0) || (ry
< 0)) {
2338 * Special case for rx=0 - draw a vline
2341 return (vlineColor(dst
, x
, y
- ry
, y
+ ry
, color
));
2344 * Special case for ry=0 - draw a hline
2347 return (hlineColor(dst
, x
- rx
, x
+ rx
, y
, color
));
2357 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
2364 oh
= oi
= oj
= ok
= 0xFFFF;
2372 if (SDL_MUSTLOCK(dst
)) {
2373 if (SDL_LockSurface(dst
) < 0) {
2381 if ((color
& 255) == 255) {
2384 * No Alpha - direct memory writes
2390 colorptr
= (Uint8
*) & color
;
2391 if (SDL_BYTEORDER
== SDL_BIG_ENDIAN
) {
2392 color
= SDL_MapRGBA(dst
->format
, colorptr
[0], colorptr
[1], colorptr
[2], colorptr
[3]);
2394 color
= SDL_MapRGBA(dst
->format
, colorptr
[3], colorptr
[2], colorptr
[1], colorptr
[0]);
2408 if (((ok
!= k
) && (oj
!= k
)) || ((oj
!= j
) && (ok
!= j
)) || (k
!= j
)) {
2414 result
|= fastPixelColorNolock(dst
, xmh
, ypk
, color
);
2415 result
|= fastPixelColorNolock(dst
, xph
, ypk
, color
);
2416 result
|= fastPixelColorNolock(dst
, xmh
, ymk
, color
);
2417 result
|= fastPixelColorNolock(dst
, xph
, ymk
, color
);
2419 result
|= fastPixelColorNolock(dst
, xmh
, y
, color
);
2420 result
|= fastPixelColorNolock(dst
, xph
, y
, color
);
2428 result
|= fastPixelColorNolock(dst
, xmi
, ypj
, color
);
2429 result
|= fastPixelColorNolock(dst
, xpi
, ypj
, color
);
2430 result
|= fastPixelColorNolock(dst
, xmi
, ymj
, color
);
2431 result
|= fastPixelColorNolock(dst
, xpi
, ymj
, color
);
2433 result
|= fastPixelColorNolock(dst
, xmi
, y
, color
);
2434 result
|= fastPixelColorNolock(dst
, xpi
, y
, color
);
2453 if (((oi
!= i
) && (oh
!= i
)) || ((oh
!= h
) && (oi
!= h
) && (i
!= h
))) {
2459 result
|= fastPixelColorNolock(dst
, xmj
, ypi
, color
);
2460 result
|= fastPixelColorNolock(dst
, xpj
, ypi
, color
);
2461 result
|= fastPixelColorNolock(dst
, xmj
, ymi
, color
);
2462 result
|= fastPixelColorNolock(dst
, xpj
, ymi
, color
);
2464 result
|= fastPixelColorNolock(dst
, xmj
, y
, color
);
2465 result
|= fastPixelColorNolock(dst
, xpj
, y
, color
);
2473 result
|= fastPixelColorNolock(dst
, xmk
, yph
, color
);
2474 result
|= fastPixelColorNolock(dst
, xpk
, yph
, color
);
2475 result
|= fastPixelColorNolock(dst
, xmk
, ymh
, color
);
2476 result
|= fastPixelColorNolock(dst
, xpk
, ymh
, color
);
2478 result
|= fastPixelColorNolock(dst
, xmk
, y
, color
);
2479 result
|= fastPixelColorNolock(dst
, xpk
, y
, color
);
2502 if (((ok
!= k
) && (oj
!= k
)) || ((oj
!= j
) && (ok
!= j
)) || (k
!= j
)) {
2508 result
|= pixelColorNolock (dst
, xmh
, ypk
, color
);
2509 result
|= pixelColorNolock (dst
, xph
, ypk
, color
);
2510 result
|= pixelColorNolock (dst
, xmh
, ymk
, color
);
2511 result
|= pixelColorNolock (dst
, xph
, ymk
, color
);
2513 result
|= pixelColorNolock (dst
, xmh
, y
, color
);
2514 result
|= pixelColorNolock (dst
, xph
, y
, color
);
2522 result
|= pixelColorNolock (dst
, xmi
, ypj
, color
);
2523 result
|= pixelColorNolock (dst
, xpi
, ypj
, color
);
2524 result
|= pixelColorNolock (dst
, xmi
, ymj
, color
);
2525 result
|= pixelColor(dst
, xpi
, ymj
, color
);
2527 result
|= pixelColorNolock (dst
, xmi
, y
, color
);
2528 result
|= pixelColorNolock (dst
, xpi
, y
, color
);
2547 if (((oi
!= i
) && (oh
!= i
)) || ((oh
!= h
) && (oi
!= h
) && (i
!= h
))) {
2553 result
|= pixelColorNolock (dst
, xmj
, ypi
, color
);
2554 result
|= pixelColorNolock (dst
, xpj
, ypi
, color
);
2555 result
|= pixelColorNolock (dst
, xmj
, ymi
, color
);
2556 result
|= pixelColorNolock (dst
, xpj
, ymi
, color
);
2558 result
|= pixelColorNolock (dst
, xmj
, y
, color
);
2559 result
|= pixelColorNolock (dst
, xpj
, y
, color
);
2567 result
|= pixelColorNolock (dst
, xmk
, yph
, color
);
2568 result
|= pixelColorNolock (dst
, xpk
, yph
, color
);
2569 result
|= pixelColorNolock (dst
, xmk
, ymh
, color
);
2570 result
|= pixelColorNolock (dst
, xpk
, ymh
, color
);
2572 result
|= pixelColorNolock (dst
, xmk
, y
, color
);
2573 result
|= pixelColorNolock (dst
, xpk
, y
, color
);
2586 /* Unlock surface */
2587 if (SDL_MUSTLOCK(dst
)) {
2588 SDL_UnlockSurface(dst
);
2594 int ellipseRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rx
, Sint16 ry
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
2599 return (ellipseColor(dst
, x
, y
, rx
, ry
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
2602 /* ----- AA Ellipse */
2604 /* Based on code from Anders Lindstroem, based on code from SGE, based on code from TwinLib */
2606 int aaellipseColor(SDL_Surface
* dst
, Sint16 xc
, Sint16 yc
, Sint16 rx
, Sint16 ry
, Uint32 color
)
2609 int a2
, b2
, ds
, dt
, dxt
, t
, s
, d
;
2610 Sint16 x
, y
, xs
, ys
, dyt
, xx
, yy
, xc2
, yc2
;
2612 Uint8 weight
, iweight
;
2615 /* Sanity check radius */
2621 /* Variable setup */
2631 dxt
= (int) (a2
/ sqrt(a2
+ b2
));
2645 if (SDL_MUSTLOCK(dst
)) {
2646 if (SDL_LockSurface(dst
) < 0) {
2652 result
|= pixelColorNolock(dst
, x
, y
, color
);
2653 result
|= pixelColorNolock(dst
, xc2
- x
, y
, color
);
2654 result
|= pixelColorNolock(dst
, x
, yc2
- y
, color
);
2655 result
|= pixelColorNolock(dst
, xc2
- x
, yc2
- y
, color
);
2657 for (i
= 1; i
<= dxt
; i
++) {
2663 else if ((d
- s
- a2
) > 0) {
2664 if ((2 * d
- s
- a2
) >= 0)
2681 /* Calculate alpha */
2683 cp
= (float) abs(d
) / (float) abs(s
);
2691 /* Calculate weights */
2692 weight
= (Uint8
) (cp
* 255);
2693 iweight
= 255 - weight
;
2697 result
|= pixelColorWeightNolock(dst
, x
, y
, color
, iweight
);
2698 result
|= pixelColorWeightNolock(dst
, xx
, y
, color
, iweight
);
2700 result
|= pixelColorWeightNolock(dst
, x
, ys
, color
, weight
);
2701 result
|= pixelColorWeightNolock(dst
, xx
, ys
, color
, weight
);
2705 result
|= pixelColorWeightNolock(dst
, x
, yy
, color
, iweight
);
2706 result
|= pixelColorWeightNolock(dst
, xx
, yy
, color
, iweight
);
2709 result
|= pixelColorWeightNolock(dst
, x
, yy
, color
, weight
);
2710 result
|= pixelColorWeightNolock(dst
, xx
, yy
, color
, weight
);
2715 for (i
= 1; i
<= dyt
; i
++) {
2721 else if ((d
+ t
- b2
) < 0) {
2722 if ((2 * d
+ t
- b2
) <= 0)
2739 /* Calculate alpha */
2741 cp
= (float) abs(d
) / (float) abs(t
);
2749 /* Calculate weight */
2750 weight
= (Uint8
) (cp
* 255);
2751 iweight
= 255 - weight
;
2756 result
|= pixelColorWeightNolock(dst
, x
, y
, color
, iweight
);
2757 result
|= pixelColorWeightNolock(dst
, xx
, y
, color
, iweight
);
2759 result
|= pixelColorWeightNolock(dst
, x
, yy
, color
, iweight
);
2760 result
|= pixelColorWeightNolock(dst
, xx
, yy
, color
, iweight
);
2764 result
|= pixelColorWeightNolock(dst
, xs
, y
, color
, weight
);
2765 result
|= pixelColorWeightNolock(dst
, xx
, y
, color
, weight
);
2767 result
|= pixelColorWeightNolock(dst
, xs
, yy
, color
, weight
);
2768 result
|= pixelColorWeightNolock(dst
, xx
, yy
, color
, weight
);
2773 /* Unlock surface */
2774 if (SDL_MUSTLOCK(dst
)) {
2775 SDL_UnlockSurface(dst
);
2781 int aaellipseRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rx
, Sint16 ry
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
2786 return (aaellipseColor
2787 (dst
, x
, y
, rx
, ry
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
2790 /* ---- Filled Ellipse */
2793 /* Based on algorithm from sge library with multiple-hline draw removal */
2794 /* and other speedup changes. */
2796 int filledEllipseColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rx
, Sint16 ry
, Uint32 color
)
2799 Sint16 x1
, y1
, x2
, y2
;
2809 * Sanity check radii
2811 if ((rx
< 0) || (ry
< 0)) {
2816 * Special case for rx=0 - draw a vline
2819 return (vlineColor(dst
, x
, y
- ry
, y
+ ry
, color
));
2822 * Special case for ry=0 - draw a hline
2825 return (hlineColor(dst
, x
- rx
, x
+ rx
, y
, color
));
2835 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
2842 oh
= oi
= oj
= ok
= 0xFFFF;
2858 if ((ok
!= k
) && (oj
!= k
)) {
2862 result
|= hlineColor(dst
, xmh
, xph
, y
+ k
, color
);
2863 result
|= hlineColor(dst
, xmh
, xph
, y
- k
, color
);
2865 result
|= hlineColor(dst
, xmh
, xph
, y
, color
);
2869 if ((oj
!= j
) && (ok
!= j
) && (k
!= j
)) {
2873 result
|= hlineColor(dst
, xmi
, xpi
, y
+ j
, color
);
2874 result
|= hlineColor(dst
, xmi
, xpi
, y
- j
, color
);
2876 result
|= hlineColor(dst
, xmi
, xpi
, y
, color
);
2895 if ((oi
!= i
) && (oh
!= i
)) {
2899 result
|= hlineColor(dst
, xmj
, xpj
, y
+ i
, color
);
2900 result
|= hlineColor(dst
, xmj
, xpj
, y
- i
, color
);
2902 result
|= hlineColor(dst
, xmj
, xpj
, y
, color
);
2906 if ((oh
!= h
) && (oi
!= h
) && (i
!= h
)) {
2910 result
|= hlineColor(dst
, xmk
, xpk
, y
+ h
, color
);
2911 result
|= hlineColor(dst
, xmk
, xpk
, y
- h
, color
);
2913 result
|= hlineColor(dst
, xmk
, xpk
, y
, color
);
2928 int filledEllipseRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rx
, Sint16 ry
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
2933 return (filledEllipseColor
2934 (dst
, x
, y
, rx
, ry
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
2937 /* ----- filled pie */
2939 /* Low-speed float pie-calc implementation by drawing polygons. */
2941 int filledpieColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rad
, Sint16 start
, Sint16 end
, Uint32 color
)
2944 Sint16 x1
, y1
, x2
, y2
;
2945 double angle
, start_angle
, end_angle
;
2953 * Sanity check radii
2962 start
= start
% 360;
2966 * Special case for rad=0 - draw a point
2969 return (pixelColor(dst
, x
, y
, color
));
2973 * Test bounding box for visibility
2979 if (!(clipLine(dst
, &x1
, &y1
, &x2
, &y2
))) {
2987 deltaAngle
= 3.0 / dr
;
2988 start_angle
= (double) start
*(2.0 * M_PI
/ 360.0);
2989 end_angle
= (double) end
*(2.0 * M_PI
/ 360.0);
2991 end_angle
+= (2.0 * M_PI
);
2994 /* Count points (rather than calculate it) */
2996 angle
= start_angle
;
2997 while (angle
<= end_angle
) {
2998 angle
+= deltaAngle
;
3002 /* Check size of array */
3003 if (numpoints
== 1) {
3004 return (pixelColor(dst
, x
, y
, color
));
3005 } else if (numpoints
== 2) {
3006 posX
= x
+ (int) (dr
* cos(start_angle
));
3007 posY
= y
+ (int) (dr
* sin(start_angle
));
3008 return (lineColor(dst
, x
, y
, posX
, posY
, color
));
3011 /* Allocate vertex array */
3012 vx
= vy
= (Uint16
*) malloc(2 * sizeof(Uint16
) * numpoints
);
3022 /* Calculate and store vertices */
3024 angle
= start_angle
;
3025 while (angle
<= end_angle
) {
3026 vx
[i
] = x
+ (int) (dr
* cos(angle
));
3027 vy
[i
] = y
+ (int) (dr
* sin(angle
));
3028 angle
+= deltaAngle
;
3033 result
= filledPolygonColor(dst
, vx
, vy
, numpoints
, color
);
3041 int filledpieRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, Sint16 rad
,
3042 Sint16 start
, Sint16 end
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
3044 return (filledpieColor(dst
, x
, y
, rad
, start
, end
,
3045 ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
3051 int polygonColor(SDL_Surface
* dst
, Sint16
* vx
, Sint16
* vy
, int n
, Uint32 color
)
3055 Sint16
*x1
, *y1
, *x2
, *y2
;
3076 for (i
= 1; i
< n
; i
++) {
3077 result
|= lineColor(dst
, *x1
, *y1
, *x2
, *y2
, color
);
3083 result
|= lineColor(dst
, *x1
, *y1
, *vx
, *vy
, color
);
3088 int polygonRGBA(SDL_Surface
* dst
, Sint16
* vx
, Sint16
* vy
, int n
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
3093 return (polygonColor(dst
, vx
, vy
, n
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
3096 /* ---- AA-Polygon */
3098 int aapolygonColor(SDL_Surface
* dst
, Sint16
* vx
, Sint16
* vy
, int n
, Uint32 color
)
3102 Sint16
*x1
, *y1
, *x2
, *y2
;
3123 for (i
= 1; i
< n
; i
++) {
3124 result
|= aalineColorInt(dst
, *x1
, *y1
, *x2
, *y2
, color
, 0);
3130 result
|= aalineColorInt(dst
, *x1
, *y1
, *vx
, *vy
, color
, 0);
3135 int aapolygonRGBA(SDL_Surface
* dst
, Sint16
* vx
, Sint16
* vy
, int n
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
3140 return (aapolygonColor(dst
, vx
, vy
, n
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
3143 /* ---- Filled Polygon */
3145 int gfxPrimitivesCompareInt(const void *a
, const void *b
);
3147 static int *gfxPrimitivesPolyInts
= NULL
;
3148 static int gfxPrimitivesPolyAllocated
= 0;
3150 int filledPolygonColor(SDL_Surface
* dst
, Sint16
* vx
, Sint16
* vy
, int n
, int color
)
3169 * Allocate temp array, only grow array
3171 if (!gfxPrimitivesPolyAllocated
) {
3172 gfxPrimitivesPolyInts
= (int *) malloc(sizeof(int) * n
);
3173 gfxPrimitivesPolyAllocated
= n
;
3175 if (gfxPrimitivesPolyAllocated
< n
) {
3176 gfxPrimitivesPolyInts
= (int *) realloc(gfxPrimitivesPolyInts
, sizeof(int) * n
);
3177 gfxPrimitivesPolyAllocated
= n
;
3182 * Determine Y maxima
3186 for (i
= 1; (i
< n
); i
++) {
3189 } else if (vy
[i
] > maxy
) {
3198 for (y
= miny
; (y
<= maxy
); y
++) {
3200 for (i
= 0; (i
< n
); i
++) {
3213 } else if (y1
> y2
) {
3221 if ((y
>= y1
) && (y
< y2
)) {
3222 gfxPrimitivesPolyInts
[ints
++] = (y
- y1
) * (x2
- x1
) / (y2
- y1
) + x1
;
3223 } else if ((y
== maxy
) && (y
> y1
) && (y
<= y2
)) {
3224 gfxPrimitivesPolyInts
[ints
++] = (y
- y1
) * (x2
- x1
) / (y2
- y1
) + x1
;
3227 qsort(gfxPrimitivesPolyInts
, ints
, sizeof(int), gfxPrimitivesCompareInt
);
3229 for (i
= 0; (i
< ints
); i
+= 2) {
3230 result
|= hlineColor(dst
, gfxPrimitivesPolyInts
[i
], gfxPrimitivesPolyInts
[i
+ 1], y
, color
);
3237 int filledPolygonRGBA(SDL_Surface
* dst
, Sint16
* vx
, Sint16
* vy
, int n
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
3242 return (filledPolygonColor
3243 (dst
, vx
, vy
, n
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
3246 int gfxPrimitivesCompareInt(const void *a
, const void *b
)
3248 return (*(const int *) a
) - (*(const int *) b
);
3251 /* ---- Character (8x8 internal font) */
3253 static SDL_Surface
*gfxPrimitivesFont
[256];
3254 static Uint32 gfxPrimitivesFontColor
[256];
3256 int characterColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, char c
, Uint32 color
)
3262 unsigned char *charpos
;
3263 unsigned char bits
[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
3264 unsigned char *bitpos
;
3269 * Setup source rectangle for 8x8 bitmap
3277 * Setup destination rectangle for 8x8 bitmap
3285 * Create new 8x8 bitmap surface if not already present
3287 if (gfxPrimitivesFont
[(unsigned char) c
] == NULL
) {
3288 gfxPrimitivesFont
[(unsigned char) c
] =
3289 SDL_CreateRGBSurface(SDL_SWSURFACE
| SDL_HWSURFACE
| SDL_SRCALPHA
, 8, 8,
3290 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
3294 if (gfxPrimitivesFont
[(unsigned char) c
] == NULL
) {
3306 * Check if color has changed
3308 if ((gfxPrimitivesFontColor
[(unsigned char) c
] != color
) || (forced_redraw
)) {
3312 SDL_SetAlpha(gfxPrimitivesFont
[(unsigned char) c
], SDL_SRCALPHA
, 255);
3313 gfxPrimitivesFontColor
[(unsigned char) c
] = color
;
3318 k
= (unsigned char) c
;
3320 charpos
= gfxPrimitivesFontdata
;
3326 curpos
= (Uint8
*) gfxPrimitivesFont
[(unsigned char) c
]->pixels
;
3327 memset(curpos
, 0, 8 * 8 * 4);
3332 for (iy
= 0; iy
< 8; iy
++) {
3334 for (ix
= 0; ix
< 8; ix
++) {
3335 if ((*charpos
& *bitpos
) == *bitpos
) {
3336 memcpy(curpos
, &color
, 4);
3346 * Draw bitmap onto destination surface
3348 result
= SDL_BlitSurface(gfxPrimitivesFont
[(unsigned char) c
], &srect
, dst
, &drect
);
3353 int characterRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, char c
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
3358 return (characterColor(dst
, x
, y
, c
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));
3361 int stringColor(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, char *c
, Uint32 color
)
3372 for (i
= 0; i
< length
; i
++) {
3373 result
|= characterColor(dst
, curx
, y
, *curchar
, color
);
3381 int stringRGBA(SDL_Surface
* dst
, Sint16 x
, Sint16 y
, char *c
, Uint8 r
, Uint8 g
, Uint8 b
, Uint8 a
)
3386 return (stringColor(dst
, x
, y
, c
, ((Uint32
) r
<< 24) | ((Uint32
) g
<< 16) | ((Uint32
) b
<< 8) | (Uint32
) a
));