#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "SDL_gfxPrimitives.h"
#include "SDL_gfxPrimitives_font.h"
#define clip_xmin(surface) surface->clip_rect.x
#define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
#define clip_ymin(surface) surface->clip_rect.y
#define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
int fastPixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
{
int bpp;
Uint8 *p;
if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst)) && (y <= clip_ymax(dst))) {
bpp = dst->format->BytesPerPixel;
p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
switch (bpp) {
case 1:
*p = color;
break;
case 2:
*(Uint16 *) p = color;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (color >> 16) & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = color & 0xff;
} else {
p[0] = color & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = (color >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *) p = color;
break;
}
}
return (0);
}
int fastPixelColorNolockNoclip(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
{
int bpp;
Uint8 *p;
bpp = dst->format->BytesPerPixel;
p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
switch (bpp) {
case 1:
*p = color;
break;
case 2:
*(Uint16 *) p = color;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
p[0] = (color >> 16) & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = color & 0xff;
} else {
p[0] = color & 0xff;
p[1] = (color >> 8) & 0xff;
p[2] = (color >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *) p = color;
break;
}
return (0);
}
int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
{
int result;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
result = fastPixelColorNolock(dst, x, y, color);
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (result);
}
int fastPixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
Uint32 color;
color = SDL_MapRGBA(dst->format, r, g, b, a);
return (fastPixelColor(dst, x, y, color));
}
int fastPixelRGBANolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
Uint32 color;
color = SDL_MapRGBA(dst->format, r, g, b, a);
return (fastPixelColorNolock(dst, x, y, color));
}
int _putPixelAlpha(SDL_Surface * surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
{
Uint32 Rmask = surface->format->Rmask, Gmask =
surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
Uint32 R, G, B, A = 0;
if (x >= clip_xmin(surface) && x <= clip_xmax(surface)
&& y >= clip_ymin(surface) && y <= clip_ymax(surface)) {
switch (surface->format->BytesPerPixel) {
case 1:{
if (alpha == 255) {
*((Uint8 *) surface->pixels + y * surface->pitch + x) = color;
} else {
Uint8 *pixel = (Uint8 *) surface->pixels + y * surface->pitch + x;
Uint8 dR = surface->format->palette->colors[*pixel].r;
Uint8 dG = surface->format->palette->colors[*pixel].g;
Uint8 dB = surface->format->palette->colors[*pixel].b;
Uint8 sR = surface->format->palette->colors[color].r;
Uint8 sG = surface->format->palette->colors[color].g;
Uint8 sB = surface->format->palette->colors[color].b;
dR = dR + ((sR - dR) * alpha >> 8);
dG = dG + ((sG - dG) * alpha >> 8);
dB = dB + ((sB - dB) * alpha >> 8);
*pixel = SDL_MapRGB(surface->format, dR, dG, dB);
}
}
break;
case 2:{
if (alpha == 255) {
*((Uint16 *) surface->pixels + y * surface->pitch / 2 + x) = color;
} else {
Uint16 *pixel = (Uint16 *) surface->pixels + y * surface->pitch / 2 + x;
Uint32 dc = *pixel;
R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
if (Amask)
A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
*pixel = R | G | B | A;
}
}
break;
case 3:{
Uint8 *pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3;
Uint8 rshift8 = surface->format->Rshift / 8;
Uint8 gshift8 = surface->format->Gshift / 8;
Uint8 bshift8 = surface->format->Bshift / 8;
Uint8 ashift8 = surface->format->Ashift / 8;
if (alpha == 255) {
*(pix + rshift8) = color >> surface->format->Rshift;
*(pix + gshift8) = color >> surface->format->Gshift;
*(pix + bshift8) = color >> surface->format->Bshift;
*(pix + ashift8) = color >> surface->format->Ashift;
} else {
Uint8 dR, dG, dB, dA = 0;
Uint8 sR, sG, sB, sA = 0;
pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3;
dR = *((pix) + rshift8);
dG = *((pix) + gshift8);
dB = *((pix) + bshift8);
dA = *((pix) + ashift8);
sR = (color >> surface->format->Rshift) & 0xff;
sG = (color >> surface->format->Gshift) & 0xff;
sB = (color >> surface->format->Bshift) & 0xff;
sA = (color >> surface->format->Ashift) & 0xff;
dR = dR + ((sR - dR) * alpha >> 8);
dG = dG + ((sG - dG) * alpha >> 8);
dB = dB + ((sB - dB) * alpha >> 8);
dA = dA + ((sA - dA) * alpha >> 8);
*((pix) + rshift8) = dR;
*((pix) + gshift8) = dG;
*((pix) + bshift8) = dB;
*((pix) + ashift8) = dA;
}
}
break;
case 4:{
if (alpha == 255) {
*((Uint32 *) surface->pixels + y * surface->pitch / 4 + x) = color;
} else {
Uint32 *pixel = (Uint32 *) surface->pixels + y * surface->pitch / 4 + x;
Uint32 dc = *pixel;
R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
if (Amask)
A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
*pixel = R | G | B | A;
}
}
break;
}
}
return (0);
}
int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
{
Uint8 alpha;
Uint32 mcolor;
int result = 0;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
alpha = color & 0x000000ff;
mcolor =
SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
(color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
result = _putPixelAlpha(dst, x, y, mcolor, alpha);
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (result);
}
int pixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
{
Uint8 alpha;
Uint32 mcolor;
int result = 0;
alpha = color & 0x000000ff;
mcolor =
SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
(color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
result = _putPixelAlpha(dst, x, y, mcolor, alpha);
return (result);
}
int _filledRectAlpha(SDL_Surface * surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
{
Uint32 Rmask = surface->format->Rmask, Gmask =
surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
Uint32 R, G, B, A = 0;
Sint16 x, y;
switch (surface->format->BytesPerPixel) {
case 1:{
Uint8 *row, *pixel;
Uint8 dR, dG, dB;
Uint8 sR = surface->format->palette->colors[color].r;
Uint8 sG = surface->format->palette->colors[color].g;
Uint8 sB = surface->format->palette->colors[color].b;
for (y = y1; y <= y2; y++) {
row = (Uint8 *) surface->pixels + y * surface->pitch;
for (x = x1; x <= x2; x++) {
pixel = row + x;
dR = surface->format->palette->colors[*pixel].r;
dG = surface->format->palette->colors[*pixel].g;
dB = surface->format->palette->colors[*pixel].b;
dR = dR + ((sR - dR) * alpha >> 8);
dG = dG + ((sG - dG) * alpha >> 8);
dB = dB + ((sB - dB) * alpha >> 8);
*pixel = SDL_MapRGB(surface->format, dR, dG, dB);
}
}
}
break;
case 2:{
Uint16 *row, *pixel;
Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
for (y = y1; y <= y2; y++) {
row = (Uint16 *) surface->pixels + y * surface->pitch / 2;
for (x = x1; x <= x2; x++) {
pixel = row + x;
R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
if (Amask)
A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
*pixel = R | G | B | A;
}
}
}
break;
case 3:{
Uint8 *row, *pix;
Uint8 dR, dG, dB, dA;
Uint8 rshift8 = surface->format->Rshift / 8;
Uint8 gshift8 = surface->format->Gshift / 8;
Uint8 bshift8 = surface->format->Bshift / 8;
Uint8 ashift8 = surface->format->Ashift / 8;
Uint8 sR = (color >> surface->format->Rshift) & 0xff;
Uint8 sG = (color >> surface->format->Gshift) & 0xff;
Uint8 sB = (color >> surface->format->Bshift) & 0xff;
Uint8 sA = (color >> surface->format->Ashift) & 0xff;
for (y = y1; y <= y2; y++) {
row = (Uint8 *) surface->pixels + y * surface->pitch;
for (x = x1; x <= x2; x++) {
pix = row + x * 3;
dR = *((pix) + rshift8);
dG = *((pix) + gshift8);
dB = *((pix) + bshift8);
dA = *((pix) + ashift8);
dR = dR + ((sR - dR) * alpha >> 8);
dG = dG + ((sG - dG) * alpha >> 8);
dB = dB + ((sB - dB) * alpha >> 8);
dA = dA + ((sA - dA) * alpha >> 8);
*((pix) + rshift8) = dR;
*((pix) + gshift8) = dG;
*((pix) + bshift8) = dB;
*((pix) + ashift8) = dA;
}
}
}
break;
case 4:{
Uint32 *row, *pixel;
Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
for (y = y1; y <= y2; y++) {
row = (Uint32 *) surface->pixels + y * surface->pitch / 4;
for (x = x1; x <= x2; x++) {
pixel = row + x;
R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
if (Amask)
A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
*pixel = R | G | B | A;
}
}
}
break;
}
return (0);
}
int filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
Uint8 alpha;
Uint32 mcolor;
int result = 0;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
alpha = color & 0x000000ff;
mcolor =
SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
(color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
result = _filledRectAlpha(dst, x1, y1, x2, y2, mcolor, alpha);
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (result);
}
int HLineAlpha(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
{
return (filledRectAlpha(dst, x1, y, x2, y, color));
}
int VLineAlpha(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
{
return (filledRectAlpha(dst, x, y1, x, y2, color));
}
int pixelColorWeight(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
{
Uint32 a;
a = (color & (Uint32) 0x000000ff);
a = ((a * weight) >> 8);
return (pixelColor(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
}
int pixelColorWeightNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
{
Uint32 a;
a = (color & (Uint32) 0x000000ff);
a = ((a * weight) >> 8);
return (pixelColorNolock(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
}
int pixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
Uint32 color;
if (a == 255) {
color = SDL_MapRGBA(dst->format, r, g, b, a);
return (fastPixelColor(dst, x, y, color));
} else {
return (pixelColor(dst, x, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
}
int hlineColorStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
{
Sint16 left, right, top, bottom;
Uint8 *pixel, *pixellast;
int dx;
int pixx, pixy;
Sint16 w;
Sint16 xtmp;
int result = -1;
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y<top) || (y>bottom)) {
return (0);
}
if (x1 < left) {
x1 = left;
}
if (x2 > right) {
x2 = right;
}
if (x1 > x2) {
xtmp = x1;
x1 = x2;
x2 = xtmp;
}
w = x2 - x1;
if (w < 0) {
return (0);
}
SDL_LockSurface(dst);
dx = w;
pixx = dst->format->BytesPerPixel;
pixy = dst->pitch;
pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
switch (dst->format->BytesPerPixel) {
case 1:
memset(pixel, color, dx);
break;
case 2:
pixellast = pixel + dx + dx;
for (; pixel <= pixellast; pixel += pixx) {
*(Uint16 *) pixel = color;
}
break;
case 3:
pixellast = pixel + dx + dx + dx;
for (; pixel <= pixellast; pixel += pixx) {
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
pixel[0] = (color >> 16) & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = color & 0xff;
} else {
pixel[0] = color & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = (color >> 16) & 0xff;
}
}
break;
default:
dx = dx + dx;
pixellast = pixel + dx + dx;
for (; pixel <= pixellast; pixel += pixx) {
*(Uint32 *) pixel = color;
}
break;
}
SDL_UnlockSurface(dst);
result = 0;
return (result);
}
int hlineRGBAStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (hlineColorStore(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int hlineColor(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
{
Sint16 left, right, top, bottom;
Uint8 *pixel, *pixellast;
int dx;
int pixx, pixy;
Sint16 w;
Sint16 xtmp;
int result = -1;
Uint8 *colorptr;
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y<top) || (y>bottom)) {
return (0);
}
if (x1 < left) {
x1 = left;
}
if (x2 > right) {
x2 = right;
}
if (x1 > x2) {
xtmp = x1;
x1 = x2;
x2 = xtmp;
}
w = x2 - x1;
if (w < 0) {
return (0);
}
if ((color & 255) == 255) {
colorptr = (Uint8 *) & color;
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
} else {
color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
}
SDL_LockSurface(dst);
dx = w;
pixx = dst->format->BytesPerPixel;
pixy = dst->pitch;
pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
switch (dst->format->BytesPerPixel) {
case 1:
memset(pixel, color, dx);
break;
case 2:
pixellast = pixel + dx + dx;
for (; pixel <= pixellast; pixel += pixx) {
*(Uint16 *) pixel = color;
}
break;
case 3:
pixellast = pixel + dx + dx + dx;
for (; pixel <= pixellast; pixel += pixx) {
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
pixel[0] = (color >> 16) & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = color & 0xff;
} else {
pixel[0] = color & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = (color >> 16) & 0xff;
}
}
break;
default:
dx = dx + dx;
pixellast = pixel + dx + dx;
for (; pixel <= pixellast; pixel += pixx) {
*(Uint32 *) pixel = color;
}
break;
}
SDL_UnlockSurface(dst);
result = 0;
} else {
result = HLineAlpha(dst, x1, x1 + w, y, color);
}
return (result);
}
int hlineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (hlineColor(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int vlineColor(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
{
Sint16 left, right, top, bottom;
Uint8 *pixel, *pixellast;
int dy;
int pixx, pixy;
Sint16 h;
Sint16 ytmp;
int result = -1;
Uint8 *colorptr;
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
if ((x<left) || (x>right)) {
return (0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
if (y1 < top) {
y1 = top;
}
if (y2 > bottom) {
y2 = bottom;
}
if (y1 > y2) {
ytmp = y1;
y1 = y2;
y2 = ytmp;
}
h = y2 - y1;
if (h < 0) {
return (0);
}
if ((color & 255) == 255) {
colorptr = (Uint8 *) & color;
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
} else {
color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
}
SDL_LockSurface(dst);
dy = h;
pixx = dst->format->BytesPerPixel;
pixy = dst->pitch;
pixel = ((Uint8 *) dst->pixels) + pixx * (int) x + pixy * (int) y1;
pixellast = pixel + pixy * dy;
switch (dst->format->BytesPerPixel) {
case 1:
for (; pixel <= pixellast; pixel += pixy) {
*(Uint8 *) pixel = color;
}
break;
case 2:
for (; pixel <= pixellast; pixel += pixy) {
*(Uint16 *) pixel = color;
}
break;
case 3:
for (; pixel <= pixellast; pixel += pixy) {
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
pixel[0] = (color >> 16) & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = color & 0xff;
} else {
pixel[0] = color & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = (color >> 16) & 0xff;
}
}
break;
default:
for (; pixel <= pixellast; pixel += pixy) {
*(Uint32 *) pixel = color;
}
break;
}
SDL_UnlockSurface(dst);
result = 0;
} else {
result = VLineAlpha(dst, x, y1, y1 + h, color);
}
return (result);
}
int vlineRGBA(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (vlineColor(dst, x, y1, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int rectangleColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
int result;
Sint16 w, h, xtmp, ytmp;
if (x1 > x2) {
xtmp = x1;
x1 = x2;
x2 = xtmp;
}
if (y1 > y2) {
ytmp = y1;
y1 = y2;
y2 = ytmp;
}
w = x2 - x1;
h = y2 - y1;
if ((w < 0) || (h < 0)) {
return (0);
}
if (x1 == x2) {
if (y1 == y2) {
return (pixelColor(dst, x1, y1, color));
} else {
return (vlineColor(dst, x1, y1, y2, color));
}
} else {
if (y1 == y2) {
return (hlineColor(dst, x1, x2, y1, color));
}
}
result = 0;
result |= hlineColor(dst, x1, x2, y1, color);
result |= hlineColor(dst, x1, x2, y2, color);
y1 += 1;
y2 -= 1;
if (y1<=y2) {
result |= vlineColor(dst, x1, y1, y2, color);
result |= vlineColor(dst, x2, y1, y2, color);
}
return (result);
}
int rectangleRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (rectangleColor
(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c
#define CLIP_LEFT_EDGE 0x1
#define CLIP_RIGHT_EDGE 0x2
#define CLIP_BOTTOM_EDGE 0x4
#define CLIP_TOP_EDGE 0x8
#define CLIP_INSIDE(a) (!a)
#define CLIP_REJECT(a,b) (a&b)
#define CLIP_ACCEPT(a,b) (!(a|b))
static int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
{
int code = 0;
if (x < left) {
code |= CLIP_LEFT_EDGE;
} else if (x > right) {
code |= CLIP_RIGHT_EDGE;
}
if (y < top) {
code |= CLIP_TOP_EDGE;
} else if (y > bottom) {
code |= CLIP_BOTTOM_EDGE;
}
return code;
}
static int clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2)
{
Sint16 left, right, top, bottom;
int code1, code2;
int draw = 0;
Sint16 swaptmp;
float m;
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
while (1) {
code1 = clipEncode(*x1, *y1, left, top, right, bottom);
code2 = clipEncode(*x2, *y2, left, top, right, bottom);
if (CLIP_ACCEPT(code1, code2)) {
draw = 1;
break;
} else if (CLIP_REJECT(code1, code2))
break;
else {
if (CLIP_INSIDE(code1)) {
swaptmp = *x2;
*x2 = *x1;
*x1 = swaptmp;
swaptmp = *y2;
*y2 = *y1;
*y1 = swaptmp;
swaptmp = code2;
code2 = code1;
code1 = swaptmp;
}
if (*x2 != *x1) {
m = (*y2 - *y1) / (float) (*x2 - *x1);
} else {
m = 1.0f;
}
if (code1 & CLIP_LEFT_EDGE) {
*y1 += (Sint16) ((left - *x1) * m);
*x1 = left;
} else if (code1 & CLIP_RIGHT_EDGE) {
*y1 += (Sint16) ((right - *x1) * m);
*x1 = right;
} else if (code1 & CLIP_BOTTOM_EDGE) {
if (*x2 != *x1) {
*x1 += (Sint16) ((bottom - *y1) / m);
}
*y1 = bottom;
} else if (code1 & CLIP_TOP_EDGE) {
if (*x2 != *x1) {
*x1 += (Sint16) ((top - *y1) / m);
}
*y1 = top;
}
}
}
return draw;
}
int boxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
Sint16 left, right, top, bottom;
Uint8 *pixel, *pixellast;
int x, dx;
int dy;
int pixx, pixy;
Sint16 w, h, tmp;
int result;
Uint8 *colorptr;
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
if (x1<left) {
x1=left;
} else if (x1>right) {
x1=right;
}
if (x2<left) {
x2=left;
} else if (x2>right) {
x2=right;
}
if (y1<top) {
y1=top;
} else if (y1>bottom) {
y1=bottom;
}
if (y2<top) {
y2=top;
} else if (y2>bottom) {
y2=bottom;
}
if (x1 > x2) {
tmp = x1;
x1 = x2;
x2 = tmp;
}
if (y1 > y2) {
tmp = y1;
y1 = y2;
y2 = tmp;
}
if (x1 == x2) {
if (y1 == y2) {
return (pixelColor(dst, x1, y1, color));
} else {
return (vlineColor(dst, x1, y1, y2, color));
}
}
if (y1 == y2) {
return (hlineColor(dst, x1, x2, y1, color));
}
w = x2 - x1;
h = y2 - y1;
if ((color & 255) == 255) {
colorptr = (Uint8 *) & color;
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
} else {
color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
}
SDL_LockSurface(dst);
dx = w;
dy = h;
pixx = dst->format->BytesPerPixel;
pixy = dst->pitch;
pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
pixellast = pixel + pixx * dx + pixy * dy;
dx++;
switch (dst->format->BytesPerPixel) {
case 1:
for (; pixel <= pixellast; pixel += pixy) {
memset(pixel, (Uint8) color, dx);
}
break;
case 2:
pixy -= (pixx * dx);
for (; pixel <= pixellast; pixel += pixy) {
for (x = 0; x < dx; x++) {
*(Uint16 *) pixel = color;
pixel += pixx;
}
}
break;
case 3:
pixy -= (pixx * dx);
for (; pixel <= pixellast; pixel += pixy) {
for (x = 0; x < dx; x++) {
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
pixel[0] = (color >> 16) & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = color & 0xff;
} else {
pixel[0] = color & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = (color >> 16) & 0xff;
}
pixel += pixx;
}
}
break;
default:
pixy -= (pixx * dx);
for (; pixel <= pixellast; pixel += pixy) {
for (x = 0; x < dx; x++) {
*(Uint32 *) pixel = color;
pixel += pixx;
}
}
break;
}
SDL_UnlockSurface(dst);
result = 0;
} else {
result = filledRectAlpha(dst, x1, y1, x1 + w, y1 + h, color);
}
return (result);
}
int boxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (boxColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
pete@shinners.org
http://pygame.seul.org
#define ABS(a) (((a)<0) ? -(a) : (a))
int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
int pixx, pixy;
int x, y;
int dx, dy;
int ax, ay;
int sx, sy;
int swaptmp;
Uint8 *pixel;
Uint8 *colorptr;
if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
return (0);
}
if (x1 == x2) {
if (y1 < y2) {
return (vlineColor(dst, x1, y1, y2, color));
} else if (y1 > y2) {
return (vlineColor(dst, x1, y2, y1, color));
} else {
return (pixelColor(dst, x1, y1, color));
}
}
if (y1 == y2) {
if (x1 < x2) {
return (hlineColor(dst, x1, x2, y1, color));
} else if (x1 > x2) {
return (hlineColor(dst, x2, x1, y1, color));
}
}
dx = x2 - x1;
dy = y2 - y1;
sx = (dx >= 0) ? 1 : -1;
sy = (dy >= 0) ? 1 : -1;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
if ((color & 255) == 255) {
colorptr = (Uint8 *) & color;
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
} else {
color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
}
dx = sx * dx + 1;
dy = sy * dy + 1;
pixx = dst->format->BytesPerPixel;
pixy = dst->pitch;
pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
pixx *= sx;
pixy *= sy;
if (dx < dy) {
swaptmp = dx;
dx = dy;
dy = swaptmp;
swaptmp = pixx;
pixx = pixy;
pixy = swaptmp;
}
x = 0;
y = 0;
switch (dst->format->BytesPerPixel) {
case 1:
for (; x < dx; x++, pixel += pixx) {
*pixel = color;
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
}
break;
case 2:
for (; x < dx; x++, pixel += pixx) {
*(Uint16 *) pixel = color;
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
}
break;
case 3:
for (; x < dx; x++, pixel += pixx) {
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
pixel[0] = (color >> 16) & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = color & 0xff;
} else {
pixel[0] = color & 0xff;
pixel[1] = (color >> 8) & 0xff;
pixel[2] = (color >> 16) & 0xff;
}
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
}
break;
default:
for (; x < dx; x++, pixel += pixx) {
*(Uint32 *) pixel = color;
y += dy;
if (y >= dx) {
y -= dx;
pixel += pixy;
}
}
break;
}
} else {
ax = ABS(dx) << 1;
ay = ABS(dy) << 1;
x = x1;
y = y1;
if (ax > ay) {
int d = ay - (ax >> 1);
while (x != x2) {
pixelColorNolock (dst, x, y, color);
if (d > 0 || (d == 0 && sx == 1)) {
y += sy;
d -= ax;
}
x += sx;
d += ay;
}
} else {
int d = ax - (ay >> 1);
while (y != y2) {
pixelColorNolock (dst, x, y, color);
if (d > 0 || ((d == 0) && (sy == 1))) {
x += sx;
d -= ay;
}
y += sy;
d += ax;
}
}
pixelColorNolock (dst, x, y, color);
}
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (0);
}
int lineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (lineColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
#define AAlevels 256
#define AAbits 8
int aalineColorInt(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint)
{
Sint32 xx0, yy0, xx1, yy1;
int result;
Uint32 intshift, erracc, erradj;
Uint32 erracctmp, wgt, wgtcompmask;
int dx, dy, tmp, xdir, y0p1, x0pxdir;
if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
return (0);
}
xx0 = x1;
yy0 = y1;
xx1 = x2;
yy1 = y2;
if (yy0 > yy1) {
tmp = yy0;
yy0 = yy1;
yy1 = tmp;
tmp = xx0;
xx0 = xx1;
xx1 = tmp;
}
dx = xx1 - xx0;
dy = yy1 - yy0;
if (dx >= 0) {
xdir = 1;
} else {
xdir = -1;
dx = (-dx);
}
if (dx == 0) {
return (vlineColor(dst, x1, y1, y2, color));
} else if (dy == 0) {
return (hlineColor(dst, x1, x2, y1, color));
} else if (dx == dy) {
return (lineColor(dst, x1, y1, x2, y2, color));
}
result = 0;
erracc = 0;
intshift = 32 - AAbits;
wgtcompmask = AAlevels - 1;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
result |= pixelColorNolock(dst, x1, y1, color);
if (dy > dx) {
erradj = ((dx << 16) / dy) << 16;
x0pxdir = xx0 + xdir;
while (--dy) {
erracctmp = erracc;
erracc += erradj;
if (erracc <= erracctmp) {
xx0 = x0pxdir;
x0pxdir += xdir;
}
yy0++;
wgt = (erracc >> intshift) & 255;
result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
result |= pixelColorWeightNolock (dst, x0pxdir, yy0, color, wgt);
}
} else {
erradj = ((dy << 16) / dx) << 16;
y0p1 = yy0 + 1;
while (--dx) {
erracctmp = erracc;
erracc += erradj;
if (erracc <= erracctmp) {
yy0 = y0p1;
y0p1++;
}
xx0 += xdir;
wgt = (erracc >> intshift) & 255;
result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
result |= pixelColorWeightNolock (dst, xx0, y0p1, color, wgt);
}
}
if (draw_endpoint) {
result |= pixelColorNolock (dst, x2, y2, color);
}
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (result);
}
int aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
{
return (aalineColorInt(dst, x1, y1, x2, y2, color, 1));
}
int aalineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (aalineColorInt
(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
}
int circleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
{
Sint16 left, right, top, bottom;
int result;
Sint16 x1, y1, x2, y2;
Sint16 cx = 0;
Sint16 cy = r;
Sint16 ocx = (Sint16) 0xffff;
Sint16 ocy = (Sint16) 0xffff;
Sint16 df = 1 - r;
Sint16 d_e = 3;
Sint16 d_se = -2 * r + 5;
Sint16 xpcx, xmcx, xpcy, xmcy;
Sint16 ypcy, ymcy, ypcx, ymcx;
Uint8 *colorptr;
if (r < 0) {
return (-1);
}
if (r == 0) {
return (pixelColor(dst, x, y, color));
}
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
x1 = x - r;
x2 = x + r;
y1 = y - r;
y2 = y + r;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
result = 0;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
if ((color & 255) == 255) {
colorptr = (Uint8 *) & color;
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
} else {
color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
}
do {
if ((ocy != cy) || (ocx != cx)) {
xpcx = x + cx;
xmcx = x - cx;
if (cy > 0) {
ypcy = y + cy;
ymcy = y - cy;
result |= fastPixelColorNolock(dst, xmcx, ypcy, color);
result |= fastPixelColorNolock(dst, xpcx, ypcy, color);
result |= fastPixelColorNolock(dst, xmcx, ymcy, color);
result |= fastPixelColorNolock(dst, xpcx, ymcy, color);
} else {
result |= fastPixelColorNolock(dst, xmcx, y, color);
result |= fastPixelColorNolock(dst, xpcx, y, color);
}
ocy = cy;
xpcy = x + cy;
xmcy = x - cy;
if (cx > 0) {
ypcx = y + cx;
ymcx = y - cx;
result |= fastPixelColorNolock(dst, xmcy, ypcx, color);
result |= fastPixelColorNolock(dst, xpcy, ypcx, color);
result |= fastPixelColorNolock(dst, xmcy, ymcx, color);
result |= fastPixelColorNolock(dst, xpcy, ymcx, color);
} else {
result |= fastPixelColorNolock(dst, xmcy, y, color);
result |= fastPixelColorNolock(dst, xpcy, y, color);
}
ocx = cx;
}
if (df < 0) {
df += d_e;
d_e += 2;
d_se += 2;
} else {
df += d_se;
d_e += 2;
d_se += 4;
cy--;
}
cx++;
} while (cx <= cy);
SDL_UnlockSurface(dst);
} else {
do {
if ((ocy != cy) || (ocx != cx)) {
xpcx = x + cx;
xmcx = x - cx;
if (cy > 0) {
ypcy = y + cy;
ymcy = y - cy;
result |= pixelColorNolock (dst, xmcx, ypcy, color);
result |= pixelColorNolock (dst, xpcx, ypcy, color);
result |= pixelColorNolock (dst, xmcx, ymcy, color);
result |= pixelColorNolock (dst, xpcx, ymcy, color);
} else {
result |= pixelColorNolock (dst, xmcx, y, color);
result |= pixelColorNolock (dst, xpcx, y, color);
}
ocy = cy;
xpcy = x + cy;
xmcy = x - cy;
if (cx > 0) {
ypcx = y + cx;
ymcx = y - cx;
result |= pixelColorNolock (dst, xmcy, ypcx, color);
result |= pixelColorNolock (dst, xpcy, ypcx, color);
result |= pixelColorNolock (dst, xmcy, ymcx, color);
result |= pixelColorNolock (dst, xpcy, ymcx, color);
} else {
result |= pixelColorNolock (dst, xmcy, y, color);
result |= pixelColorNolock (dst, xpcy, y, color);
}
ocx = cx;
}
if (df < 0) {
df += d_e;
d_e += 2;
d_se += 2;
} else {
df += d_se;
d_e += 2;
d_se += 4;
cy--;
}
cx++;
} while (cx <= cy);
}
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (result);
}
int circleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (circleColor(dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int aacircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
{
return (aaellipseColor(dst, x, y, r, r, color));
}
int aacircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (aaellipseColor
(dst, x, y, rad, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int filledCircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
{
Sint16 left, right, top, bottom;
int result;
Sint16 x1, y1, x2, y2;
Sint16 cx = 0;
Sint16 cy = r;
Sint16 ocx = (Sint16) 0xffff;
Sint16 ocy = (Sint16) 0xffff;
Sint16 df = 1 - r;
Sint16 d_e = 3;
Sint16 d_se = -2 * r + 5;
Sint16 xpcx, xmcx, xpcy, xmcy;
Sint16 ypcy, ymcy, ypcx, ymcx;
if (r < 0) {
return (-1);
}
if (r == 0) {
return (pixelColor(dst, x, y, color));
}
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
x1 = x - r;
x2 = x + r;
y1 = y - r;
y2 = y + r;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
result = 0;
do {
xpcx = x + cx;
xmcx = x - cx;
xpcy = x + cy;
xmcy = x - cy;
if (ocy != cy) {
if (cy > 0) {
ypcy = y + cy;
ymcy = y - cy;
result |= hlineColor(dst, xmcx, xpcx, ypcy, color);
result |= hlineColor(dst, xmcx, xpcx, ymcy, color);
} else {
result |= hlineColor(dst, xmcx, xpcx, y, color);
}
ocy = cy;
}
if (ocx != cx) {
if (cx != cy) {
if (cx > 0) {
ypcx = y + cx;
ymcx = y - cx;
result |= hlineColor(dst, xmcy, xpcy, ymcx, color);
result |= hlineColor(dst, xmcy, xpcy, ypcx, color);
} else {
result |= hlineColor(dst, xmcy, xpcy, y, color);
}
}
ocx = cx;
}
if (df < 0) {
df += d_e;
d_e += 2;
d_se += 2;
} else {
df += d_se;
d_e += 2;
d_se += 4;
cy--;
}
cx++;
} while (cx <= cy);
return (result);
}
int filledCircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (filledCircleColor
(dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int ellipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
{
Sint16 left, right, top, bottom;
int result;
Sint16 x1, y1, x2, y2;
int ix, iy;
int h, i, j, k;
int oh, oi, oj, ok;
int xmh, xph, ypk, ymk;
int xmi, xpi, ymj, ypj;
int xmj, xpj, ymi, ypi;
int xmk, xpk, ymh, yph;
Uint8 *colorptr;
if ((rx < 0) || (ry < 0)) {
return (-1);
}
if (rx == 0) {
return (vlineColor(dst, x, y - ry, y + ry, color));
}
if (ry == 0) {
return (hlineColor(dst, x - rx, x + rx, y, color));
}
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
x1 = x - rx;
x2 = x + rx;
y1 = y - ry;
y2 = y + ry;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
oh = oi = oj = ok = 0xFFFF;
result = 0;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
if ((color & 255) == 255) {
colorptr = (Uint8 *) & color;
if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
} else {
color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
}
if (rx > ry) {
ix = 0;
iy = rx * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * ry) / rx;
k = (i * ry) / rx;
if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
xph = x + h;
xmh = x - h;
if (k > 0) {
ypk = y + k;
ymk = y - k;
result |= fastPixelColorNolock(dst, xmh, ypk, color);
result |= fastPixelColorNolock(dst, xph, ypk, color);
result |= fastPixelColorNolock(dst, xmh, ymk, color);
result |= fastPixelColorNolock(dst, xph, ymk, color);
} else {
result |= fastPixelColorNolock(dst, xmh, y, color);
result |= fastPixelColorNolock(dst, xph, y, color);
}
ok = k;
xpi = x + i;
xmi = x - i;
if (j > 0) {
ypj = y + j;
ymj = y - j;
result |= fastPixelColorNolock(dst, xmi, ypj, color);
result |= fastPixelColorNolock(dst, xpi, ypj, color);
result |= fastPixelColorNolock(dst, xmi, ymj, color);
result |= fastPixelColorNolock(dst, xpi, ymj, color);
} else {
result |= fastPixelColorNolock(dst, xmi, y, color);
result |= fastPixelColorNolock(dst, xpi, y, color);
}
oj = j;
}
ix = ix + iy / rx;
iy = iy - ix / rx;
} while (i > h);
} else {
ix = 0;
iy = ry * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * rx) / ry;
k = (i * rx) / ry;
if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
xmj = x - j;
xpj = x + j;
if (i > 0) {
ypi = y + i;
ymi = y - i;
result |= fastPixelColorNolock(dst, xmj, ypi, color);
result |= fastPixelColorNolock(dst, xpj, ypi, color);
result |= fastPixelColorNolock(dst, xmj, ymi, color);
result |= fastPixelColorNolock(dst, xpj, ymi, color);
} else {
result |= fastPixelColorNolock(dst, xmj, y, color);
result |= fastPixelColorNolock(dst, xpj, y, color);
}
oi = i;
xmk = x - k;
xpk = x + k;
if (h > 0) {
yph = y + h;
ymh = y - h;
result |= fastPixelColorNolock(dst, xmk, yph, color);
result |= fastPixelColorNolock(dst, xpk, yph, color);
result |= fastPixelColorNolock(dst, xmk, ymh, color);
result |= fastPixelColorNolock(dst, xpk, ymh, color);
} else {
result |= fastPixelColorNolock(dst, xmk, y, color);
result |= fastPixelColorNolock(dst, xpk, y, color);
}
oh = h;
}
ix = ix + iy / ry;
iy = iy - ix / ry;
} while (i > h);
}
} else {
if (rx > ry) {
ix = 0;
iy = rx * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * ry) / rx;
k = (i * ry) / rx;
if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
xph = x + h;
xmh = x - h;
if (k > 0) {
ypk = y + k;
ymk = y - k;
result |= pixelColorNolock (dst, xmh, ypk, color);
result |= pixelColorNolock (dst, xph, ypk, color);
result |= pixelColorNolock (dst, xmh, ymk, color);
result |= pixelColorNolock (dst, xph, ymk, color);
} else {
result |= pixelColorNolock (dst, xmh, y, color);
result |= pixelColorNolock (dst, xph, y, color);
}
ok = k;
xpi = x + i;
xmi = x - i;
if (j > 0) {
ypj = y + j;
ymj = y - j;
result |= pixelColorNolock (dst, xmi, ypj, color);
result |= pixelColorNolock (dst, xpi, ypj, color);
result |= pixelColorNolock (dst, xmi, ymj, color);
result |= pixelColor(dst, xpi, ymj, color);
} else {
result |= pixelColorNolock (dst, xmi, y, color);
result |= pixelColorNolock (dst, xpi, y, color);
}
oj = j;
}
ix = ix + iy / rx;
iy = iy - ix / rx;
} while (i > h);
} else {
ix = 0;
iy = ry * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * rx) / ry;
k = (i * rx) / ry;
if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
xmj = x - j;
xpj = x + j;
if (i > 0) {
ypi = y + i;
ymi = y - i;
result |= pixelColorNolock (dst, xmj, ypi, color);
result |= pixelColorNolock (dst, xpj, ypi, color);
result |= pixelColorNolock (dst, xmj, ymi, color);
result |= pixelColorNolock (dst, xpj, ymi, color);
} else {
result |= pixelColorNolock (dst, xmj, y, color);
result |= pixelColorNolock (dst, xpj, y, color);
}
oi = i;
xmk = x - k;
xpk = x + k;
if (h > 0) {
yph = y + h;
ymh = y - h;
result |= pixelColorNolock (dst, xmk, yph, color);
result |= pixelColorNolock (dst, xpk, yph, color);
result |= pixelColorNolock (dst, xmk, ymh, color);
result |= pixelColorNolock (dst, xpk, ymh, color);
} else {
result |= pixelColorNolock (dst, xmk, y, color);
result |= pixelColorNolock (dst, xpk, y, color);
}
oh = h;
}
ix = ix + iy / ry;
iy = iy - ix / ry;
} while (i > h);
}
}
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (result);
}
int ellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (ellipseColor(dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int aaellipseColor(SDL_Surface * dst, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
{
Sint16 left, right, top, bottom;
Sint16 x1,y1,x2,y2;
int i;
int a2, b2, ds, dt, dxt, t, s, d;
Sint16 x, y, xs, ys, dyt, xx, yy, xc2, yc2;
float cp;
Uint8 weight, iweight;
int result;
if ((rx < 0) || (ry < 0)) {
return (-1);
}
if (rx == 0) {
return (vlineColor(dst, xc, yc - ry, yc + ry, color));
}
if (ry == 0) {
return (hlineColor(dst, xc - rx, xc + rx, yc, color));
}
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
x1 = xc - rx;
x2 = xc + rx;
y1 = yc - ry;
y2 = yc + ry;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
a2 = rx * rx;
b2 = ry * ry;
ds = 2 * a2;
dt = 2 * b2;
xc2 = 2 * xc;
yc2 = 2 * yc;
dxt = (int) (a2 / sqrt(a2 + b2));
t = 0;
s = -2 * a2 * ry;
d = 0;
x = xc;
y = yc - ry;
result = 0;
if (SDL_MUSTLOCK(dst)) {
if (SDL_LockSurface(dst) < 0) {
return (-1);
}
}
result |= pixelColorNolock(dst, x, y, color);
result |= pixelColorNolock(dst, xc2 - x, y, color);
result |= pixelColorNolock(dst, x, yc2 - y, color);
result |= pixelColorNolock(dst, xc2 - x, yc2 - y, color);
for (i = 1; i <= dxt; i++) {
x--;
d += t - b2;
if (d >= 0)
ys = y - 1;
else if ((d - s - a2) > 0) {
if ((2 * d - s - a2) >= 0)
ys = y + 1;
else {
ys = y;
y++;
d -= s + a2;
s += ds;
}
} else {
y++;
ys = y + 1;
d -= s + a2;
s += ds;
}
t -= dt;
if (s != 0.0) {
cp = (float) abs(d) / (float) abs(s);
if (cp > 1.0) {
cp = 1.0;
}
} else {
cp = 1.0;
}
weight = (Uint8) (cp * 255);
iweight = 255 - weight;
xx = xc2 - x;
result |= pixelColorWeightNolock(dst, x, y, color, iweight);
result |= pixelColorWeightNolock(dst, xx, y, color, iweight);
result |= pixelColorWeightNolock(dst, x, ys, color, weight);
result |= pixelColorWeightNolock(dst, xx, ys, color, weight);
yy = yc2 - y;
result |= pixelColorWeightNolock(dst, x, yy, color, iweight);
result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
yy = yc2 - ys;
result |= pixelColorWeightNolock(dst, x, yy, color, weight);
result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
}
dyt = abs(y - yc);
for (i = 1; i <= dyt; i++) {
y++;
d -= s + a2;
if (d <= 0)
xs = x + 1;
else if ((d + t - b2) < 0) {
if ((2 * d + t - b2) <= 0)
xs = x - 1;
else {
xs = x;
x--;
d += t - b2;
t -= dt;
}
} else {
x--;
xs = x - 1;
d += t - b2;
t -= dt;
}
s += ds;
if (t != 0.0) {
cp = (float) abs(d) / (float) abs(t);
if (cp > 1.0) {
cp = 1.0;
}
} else {
cp = 1.0;
}
weight = (Uint8) (cp * 255);
iweight = 255 - weight;
xx = xc2 - x;
yy = yc2 - y;
result |= pixelColorWeightNolock(dst, x, y, color, iweight);
result |= pixelColorWeightNolock(dst, xx, y, color, iweight);
result |= pixelColorWeightNolock(dst, x, yy, color, iweight);
result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
xx = 2 * xc - xs;
result |= pixelColorWeightNolock(dst, xs, y, color, weight);
result |= pixelColorWeightNolock(dst, xx, y, color, weight);
result |= pixelColorWeightNolock(dst, xs, yy, color, weight);
result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
}
if (SDL_MUSTLOCK(dst)) {
SDL_UnlockSurface(dst);
}
return (result);
}
int aaellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (aaellipseColor
(dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int filledEllipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
{
Sint16 left, right, top, bottom;
int result;
Sint16 x1, y1, x2, y2;
int ix, iy;
int h, i, j, k;
int oh, oi, oj, ok;
int xmh, xph;
int xmi, xpi;
int xmj, xpj;
int xmk, xpk;
if ((rx < 0) || (ry < 0)) {
return (-1);
}
if (rx == 0) {
return (vlineColor(dst, x, y - ry, y + ry, color));
}
if (ry == 0) {
return (hlineColor(dst, x - rx, x + rx, y, color));
}
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
x1 = x - rx;
x2 = x + rx;
y1 = y - ry;
y2 = y + ry;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
oh = oi = oj = ok = 0xFFFF;
result = 0;
if (rx > ry) {
ix = 0;
iy = rx * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * ry) / rx;
k = (i * ry) / rx;
if ((ok != k) && (oj != k)) {
xph = x + h;
xmh = x - h;
if (k > 0) {
result |= hlineColor(dst, xmh, xph, y + k, color);
result |= hlineColor(dst, xmh, xph, y - k, color);
} else {
result |= hlineColor(dst, xmh, xph, y, color);
}
ok = k;
}
if ((oj != j) && (ok != j) && (k != j)) {
xmi = x - i;
xpi = x + i;
if (j > 0) {
result |= hlineColor(dst, xmi, xpi, y + j, color);
result |= hlineColor(dst, xmi, xpi, y - j, color);
} else {
result |= hlineColor(dst, xmi, xpi, y, color);
}
oj = j;
}
ix = ix + iy / rx;
iy = iy - ix / rx;
} while (i > h);
} else {
ix = 0;
iy = ry * 64;
do {
h = (ix + 32) >> 6;
i = (iy + 32) >> 6;
j = (h * rx) / ry;
k = (i * rx) / ry;
if ((oi != i) && (oh != i)) {
xmj = x - j;
xpj = x + j;
if (i > 0) {
result |= hlineColor(dst, xmj, xpj, y + i, color);
result |= hlineColor(dst, xmj, xpj, y - i, color);
} else {
result |= hlineColor(dst, xmj, xpj, y, color);
}
oi = i;
}
if ((oh != h) && (oi != h) && (i != h)) {
xmk = x - k;
xpk = x + k;
if (h > 0) {
result |= hlineColor(dst, xmk, xpk, y + h, color);
result |= hlineColor(dst, xmk, xpk, y - h, color);
} else {
result |= hlineColor(dst, xmk, xpk, y, color);
}
oh = h;
}
ix = ix + iy / ry;
iy = iy - ix / ry;
} while (i > h);
}
return (result);
}
int filledEllipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (filledEllipseColor
(dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int doPieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color, Uint8 filled)
{
Sint16 left, right, top, bottom;
Sint16 x1, y1, x2, y2;
int result;
double angle, start_angle, end_angle;
double deltaAngle;
double dr;
int posX, posY;
int numpoints, i;
Sint16 *vx, *vy;
if (rad < 0) {
return (-1);
}
start = start % 360;
end = end % 360;
if (rad == 0) {
return (pixelColor(dst, x, y, color));
}
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
x1 = x - rad;
x2 = x + rad;
y1 = y - rad;
y2 = y + rad;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
dr = (double) rad;
deltaAngle = 3.0 / dr;
start_angle = (double) start *(2.0 * M_PI / 360.0);
end_angle = (double) end *(2.0 * M_PI / 360.0);
if (start > end) {
end_angle += (2.0 * M_PI);
}
numpoints = 1;
angle = start_angle;
while (angle <= end_angle) {
angle += deltaAngle;
numpoints++;
}
if (numpoints == 1) {
return (pixelColor(dst, x, y, color));
} else if (numpoints == 2) {
posX = x + (int) (dr * cos(start_angle));
posY = y + (int) (dr * sin(start_angle));
return (lineColor(dst, x, y, posX, posY, color));
}
vx = vy = (Uint16 *) malloc(2 * sizeof(Uint16) * numpoints);
if (vx == NULL) {
return (-1);
}
vy += numpoints;
vx[0] = x;
vy[0] = y;
i = 1;
angle = start_angle;
while (angle <= end_angle) {
vx[i] = x + (int) (dr * cos(angle));
vy[i] = y + (int) (dr * sin(angle));
angle += deltaAngle;
i++;
}
if (filled) {
result = filledPolygonColor(dst, vx, vy, numpoints, color);
} else {
result = polygonColor(dst, vx, vy, numpoints, color);
}
free(vx);
return (result);
}
int pieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
Sint16 start, Sint16 end, Uint32 color)
{
return (doPieColor(dst, x, y, rad, start, end, color, 0));
}
int pieRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (doPieColor(dst, x, y, rad, start, end,
((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 0));
}
int filledPieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
{
return (doPieColor(dst, x, y, rad, start, end, color, 1));
}
int filledPieRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (doPieColor(dst, x, y, rad, start, end,
((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
}
int trigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
{
Sint16 vx[3];
Sint16 vy[3];
vx[0]=x1;
vx[1]=x2;
vx[2]=x3;
vy[0]=y1;
vy[1]=y2;
vy[2]=y3;
return(polygonColor(dst,vx,vy,3,color));
}
int trigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
Sint16 vx[3];
Sint16 vy[3];
vx[0]=x1;
vx[1]=x2;
vx[2]=x3;
vy[0]=y1;
vy[1]=y2;
vy[2]=y3;
return(polygonRGBA(dst,vx,vy,3,r,g,b,a));
}
int aatrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
{
Sint16 vx[3];
Sint16 vy[3];
vx[0]=x1;
vx[1]=x2;
vx[2]=x3;
vy[0]=y1;
vy[1]=y2;
vy[2]=y3;
return(aapolygonColor(dst,vx,vy,3,color));
}
int aatrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
Sint16 vx[3];
Sint16 vy[3];
vx[0]=x1;
vx[1]=x2;
vx[2]=x3;
vy[0]=y1;
vy[1]=y2;
vy[2]=y3;
return(aapolygonRGBA(dst,vx,vy,3,r,g,b,a));
}
int filledTrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
{
Sint16 vx[3];
Sint16 vy[3];
vx[0]=x1;
vx[1]=x2;
vx[2]=x3;
vy[0]=y1;
vy[1]=y2;
vy[2]=y3;
return(filledPolygonColor(dst,vx,vy,3,color));
}
int filledTrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
Sint16 vx[3];
Sint16 vy[3];
vx[0]=x1;
vx[1]=x2;
vx[2]=x3;
vy[0]=y1;
vy[1]=y2;
vy[2]=y3;
return(filledPolygonRGBA(dst,vx,vy,3,r,g,b,a));
}
int polygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
{
int result;
int i;
const Sint16 *x1, *y1, *x2, *y2;
if (n < 3) {
return (-1);
}
x1 = x2 = vx;
y1 = y2 = vy;
x2++;
y2++;
result = 0;
for (i = 1; i < n; i++) {
result |= lineColor(dst, *x1, *y1, *x2, *y2, color);
x1 = x2;
y1 = y2;
x2++;
y2++;
}
result |= lineColor(dst, *x1, *y1, *vx, *vy, color);
return (result);
}
int polygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (polygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int aapolygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
{
int result;
int i;
const Sint16 *x1, *y1, *x2, *y2;
if (n < 3) {
return (-1);
}
x1 = x2 = vx;
y1 = y2 = vy;
x2++;
y2++;
result = 0;
for (i = 1; i < n; i++) {
result |= aalineColorInt(dst, *x1, *y1, *x2, *y2, color, 0);
x1 = x2;
y1 = y2;
x2++;
y2++;
}
result |= aalineColorInt(dst, *x1, *y1, *vx, *vy, color, 0);
return (result);
}
int aapolygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (aapolygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int gfxPrimitivesCompareInt(const void *a, const void *b);
static int *gfxPrimitivesPolyInts = NULL;
static int gfxPrimitivesPolyAllocated = 0;
int filledPolygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
{
int result;
int i;
int y, xa, xb;
int miny, maxy;
int x1, y1;
int x2, y2;
int ind1, ind2;
int ints;
if (n < 3) {
return -1;
}
if (!gfxPrimitivesPolyAllocated) {
gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
gfxPrimitivesPolyAllocated = n;
} else {
if (gfxPrimitivesPolyAllocated < n) {
gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
gfxPrimitivesPolyAllocated = n;
}
}
miny = vy[0];
maxy = vy[0];
for (i = 1; (i < n); i++) {
if (vy[i] < miny) {
miny = vy[i];
} else if (vy[i] > maxy) {
maxy = vy[i];
}
}
result = 0;
for (y = miny; (y <= maxy); y++) {
ints = 0;
for (i = 0; (i < n); i++) {
if (!i) {
ind1 = n - 1;
ind2 = 0;
} else {
ind1 = i - 1;
ind2 = i;
}
y1 = vy[ind1];
y2 = vy[ind2];
if (y1 < y2) {
x1 = vx[ind1];
x2 = vx[ind2];
} else if (y1 > y2) {
y2 = vy[ind1];
y1 = vy[ind2];
x2 = vx[ind1];
x1 = vx[ind2];
} else {
continue;
}
if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
}
}
qsort(gfxPrimitivesPolyInts, ints, sizeof(int), gfxPrimitivesCompareInt);
for (i = 0; (i < ints); i += 2) {
xa = gfxPrimitivesPolyInts[i] + 1;
xa = (xa >> 16) + ((xa & 32768) >> 15);
xb = gfxPrimitivesPolyInts[i+1] - 1;
xb = (xb >> 16) + ((xb & 32768) >> 15);
result |= hlineColor(dst, xa, xb, y, color);
}
}
return (result);
}
int filledPolygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (filledPolygonColor
(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int gfxPrimitivesCompareInt(const void *a, const void *b)
{
return (*(const int *) a) - (*(const int *) b);
}
static SDL_Surface *gfxPrimitivesFont[256];
static Uint32 gfxPrimitivesFontColor[256];
static const unsigned char *currentFontdata = gfxPrimitivesFontdata;
static int charWidth = 8, charHeight = 8;
static int charPitch = 1;
static int charSize = 8;
void gfxPrimitivesSetFont(const void *fontdata, int cw, int ch)
{
int i;
if (fontdata) {
currentFontdata = fontdata;
charWidth = cw;
charHeight = ch;
} else {
currentFontdata = gfxPrimitivesFontdata;
charWidth = 8;
charHeight = 8;
}
charPitch = (charWidth+7)/8;
charSize = charPitch * charHeight;
for (i = 0; i < 256; i++) {
if (gfxPrimitivesFont[i]) {
SDL_FreeSurface(gfxPrimitivesFont[i]);
gfxPrimitivesFont[i] = NULL;
}
}
}
int characterColor(SDL_Surface * dst, Sint16 x, Sint16 y, char c, Uint32 color)
{
Sint16 left, right, top, bottom;
Sint16 x1, y1, x2, y2;
SDL_Rect srect;
SDL_Rect drect;
int result;
int ix, iy;
const unsigned char *charpos;
Uint8 *curpos;
int forced_redraw;
Uint8 patt, mask;
left = dst->clip_rect.x;
right = dst->clip_rect.x + dst->clip_rect.w - 1;
top = dst->clip_rect.y;
bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
x1 = x;
x2 = x + charWidth;
y1 = y;
y2 = y + charHeight;
if ((x1<left) && (x2<left)) {
return(0);
}
if ((x1>right) && (x2>right)) {
return(0);
}
if ((y1<top) && (y2<top)) {
return(0);
}
if ((y1>bottom) && (y2>bottom)) {
return(0);
}
srect.x = 0;
srect.y = 0;
srect.w = charWidth;
srect.h = charHeight;
drect.x = x;
drect.y = y;
drect.w = charWidth;
drect.h = charHeight;
if (gfxPrimitivesFont[(unsigned char) c] == NULL) {
gfxPrimitivesFont[(unsigned char) c] =
SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA,
charWidth, charHeight, 32,
0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
if (gfxPrimitivesFont[(unsigned char) c] == NULL) {
return (-1);
}
forced_redraw = 1;
} else {
forced_redraw = 0;
}
if ((gfxPrimitivesFontColor[(unsigned char) c] != color) || (forced_redraw)) {
SDL_SetAlpha(gfxPrimitivesFont[(unsigned char) c], SDL_SRCALPHA, 255);
gfxPrimitivesFontColor[(unsigned char) c] = color;
charpos = currentFontdata + (unsigned char) c * charSize;
curpos = (Uint8 *) gfxPrimitivesFont[(unsigned char) c]->pixels;
patt = 0;
for (iy = 0; iy < charHeight; iy++) {
mask = 0x00;
for (ix = 0; ix < charWidth; ix++) {
if (!(mask >>= 1)) {
patt = *charpos++;
mask = 0x80;
}
if (patt & mask)
*(Uint32 *)curpos = color;
else
*(Uint32 *)curpos = 0;
curpos += 4;;
}
}
}
result = SDL_BlitSurface(gfxPrimitivesFont[(unsigned char) c], &srect, dst, &drect);
return (result);
}
int characterRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (characterColor(dst, x, y, c, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
int stringColor(SDL_Surface * dst, Sint16 x, Sint16 y, const char *c, Uint32 color)
{
int result = 0;
int curx = x;
const char *curchar = c;
while (*curchar) {
result |= characterColor(dst, curx, y, *curchar, color);
curx += charWidth;
curchar++;
}
return (result);
}
int stringRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, const char *c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (stringColor(dst, x, y, c, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}
double evaluateBezier (double *data, int ndata, double t)
{
double mu, result;
int n,k,kn,nn,nkn;
double blend,muk,munk;
if (t<0.0) {
return(data[0]);
}
if (t>=(double)ndata) {
return(data[ndata-1]);
}
mu=t/(double)ndata;
n=ndata-1;
result=0.0;
muk = 1;
munk = pow(1-mu,(double)n);
for (k=0;k<=n;k++) {
nn = n;
kn = k;
nkn = n - k;
blend = muk * munk;
muk *= mu;
munk /= (1-mu);
while (nn >= 1) {
blend *= nn;
nn--;
if (kn > 1) {
blend /= (double)kn;
kn--;
}
if (nkn > 1) {
blend /= (double)nkn;
nkn--;
}
}
result += data[k] * blend;
}
return(result);
}
int bezierColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint32 color)
{
int result;
int i;
double *x, *y, t, stepsize;
Sint16 x1, y1, x2, y2;
if (n < 3) {
return (-1);
}
if (s < 2) {
return (-1);
}
stepsize=(double)1.0/(double)s;
if ((x=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
return(-1);
}
if ((y=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
free(x);
return(-1);
}
for (i=0; i<n; i++) {
x[i]=vx[i];
y[i]=vy[i];
}
x[n]=vx[0];
y[n]=vy[0];
result = 0;
t=0.0;
x1=evaluateBezier(x,n+1,t);
y1=evaluateBezier(y,n+1,t);
for (i = 0; i <= (n*s); i++) {
t += stepsize;
x2=(Sint16)evaluateBezier(x,n,t);
y2=(Sint16)evaluateBezier(y,n,t);
result |= lineColor(dst, x1, y1, x2, y2, color);
x1 = x2;
y1 = y2;
}
free(x);
free(y);
return (result);
}
int bezierRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
{
return (bezierColor(dst, vx, vy, n, s, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
}