3
SDL_gfxPrimitives - Graphics primitives for SDL surfaces
16
#include "SDL_gfxPrimitives.h"
18
/* -===================- */
20
/* Define this flag to use surface blits for alpha blended drawing. */
21
/* This is usually slower that direct surface calculations. */
23
#undef SURFACE_ALPHA_PIXEL
25
/* ----- Defines for pixel clipping tests */
27
#define clip_xmin(surface) surface->clip_rect.x
28
#define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
29
#define clip_ymin(surface) surface->clip_rect.y
30
#define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
32
/* ----- Pixel - fast, no blending, no locking, clipping */
34
int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
39
if (SDL_MUSTLOCK(dst)) {
40
if (SDL_LockSurface(dst) < 0) {
46
* Honor clipping setup at pixel level
48
if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst)) && (y <= clip_ymax(dst))) {
51
* Get destination format
53
bpp = dst->format->BytesPerPixel;
54
p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
60
*(Uint16 *) p = color;
63
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
64
p[0] = (color >> 16) & 0xff;
65
p[1] = (color >> 8) & 0xff;
69
p[1] = (color >> 8) & 0xff;
70
p[2] = (color >> 16) & 0xff;
74
*(Uint32 *) p = color;
81
if (SDL_MUSTLOCK(dst)) {
82
SDL_UnlockSurface(dst);
89
/* --------- Clipping routines for box/line */
91
/* Clipping based heavily on code from */
93
/* http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c */
95
#define CLIP_LEFT_EDGE 0x1
96
#define CLIP_RIGHT_EDGE 0x2
97
#define CLIP_BOTTOM_EDGE 0x4
98
#define CLIP_TOP_EDGE 0x8
99
#define CLIP_INSIDE(a) (!a)
100
#define CLIP_REJECT(a,b) (a&b)
101
#define CLIP_ACCEPT(a,b) (!(a|b))
103
static int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
108
code |= CLIP_LEFT_EDGE;
109
} else if (x > right) {
110
code |= CLIP_RIGHT_EDGE;
113
code |= CLIP_TOP_EDGE;
114
} else if (y > bottom) {
115
code |= CLIP_BOTTOM_EDGE;
120
static int clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2)
122
Sint16 left, right, top, bottom;
129
* Get clipping boundary
131
left = dst->clip_rect.x;
132
right = dst->clip_rect.x + dst->clip_rect.w - 1;
133
top = dst->clip_rect.y;
134
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
137
code1 = clipEncode(*x1, *y1, left, top, right, bottom);
138
code2 = clipEncode(*x2, *y2, left, top, right, bottom);
139
if (CLIP_ACCEPT(code1, code2)) {
142
} else if (CLIP_REJECT(code1, code2))
145
if (CLIP_INSIDE(code1)) {
157
m = (*y2 - *y1) / (float) (*x2 - *x1);
161
if (code1 & CLIP_LEFT_EDGE) {
162
*y1 += (Sint16) ((left - *x1) * m);
164
} else if (code1 & CLIP_RIGHT_EDGE) {
165
*y1 += (Sint16) ((right - *x1) * m);
167
} else if (code1 & CLIP_BOTTOM_EDGE) {
169
*x1 += (Sint16) ((bottom - *y1) / m);
172
} else if (code1 & CLIP_TOP_EDGE) {
174
*x1 += (Sint16) ((top - *y1) / m);
186
/* Non-alpha line drawing code adapted from routine */
187
/* by Pete Shinners, pete@shinners.org */
188
/* Originally from pygame, http://pygame.seul.org */
190
#define ABS(a) (((a)<0) ? -(a) : (a))
192
int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
202
* Clip line and test if we have to draw
204
if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
213
sx = (dx >= 0) ? 1 : -1;
214
sy = (dy >= 0) ? 1 : -1;
217
if (SDL_MUSTLOCK(dst)) {
218
if (SDL_LockSurface(dst) < 0) {
224
* Check for alpha blending
228
* More variable setup
232
pixx = dst->format->BytesPerPixel;
234
pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
251
switch (dst->format->BytesPerPixel) {
253
for (; x < dx; x++, pixel += pixx) {
263
for (; x < dx; x++, pixel += pixx) {
264
*(Uint16 *) pixel = color;
273
for (; x < dx; x++, pixel += pixx) {
274
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
275
pixel[0] = (color >> 16) & 0xff;
276
pixel[1] = (color >> 8) & 0xff;
277
pixel[2] = color & 0xff;
279
pixel[0] = color & 0xff;
280
pixel[1] = (color >> 8) & 0xff;
281
pixel[2] = (color >> 16) & 0xff;
290
default: /* case 4 */
291
for (; x < dx; x++, pixel += pixx) {
292
*(Uint32 *) pixel = color;
305
if (SDL_MUSTLOCK(dst)) {
306
SDL_UnlockSurface(dst);