00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <math.h>
00012 #include <string.h>
00013
00014 #include "SDL_gfxPrimitives.h"
00015
00016
00017
00018
00019
00020 #define clip_xmin(surface) surface->clip_rect.x
00021 #define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
00022 #define clip_ymin(surface) surface->clip_rect.y
00023 #define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
00024
00025
00026
00027 int fastPixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00028 {
00029 int bpp;
00030 Uint8 *p;
00031
00032
00033
00034
00035 if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst)) && (y <= clip_ymax(dst))) {
00036
00037
00038
00039
00040 bpp = dst->format->BytesPerPixel;
00041 p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00042 switch (bpp) {
00043 case 1:
00044 *p = color;
00045 break;
00046 case 2:
00047 *(Uint16 *) p = color;
00048 break;
00049 case 3:
00050 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00051 p[0] = (color >> 16) & 0xff;
00052 p[1] = (color >> 8) & 0xff;
00053 p[2] = color & 0xff;
00054 } else {
00055 p[0] = color & 0xff;
00056 p[1] = (color >> 8) & 0xff;
00057 p[2] = (color >> 16) & 0xff;
00058 }
00059 break;
00060 case 4:
00061 *(Uint32 *) p = color;
00062 break;
00063 }
00064
00065
00066 }
00067
00068 return (0);
00069 }
00070
00071
00072
00073
00074
00075 int fastPixelColorNolockNoclip(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00076 {
00077 int bpp;
00078 Uint8 *p;
00079
00080
00081
00082
00083 bpp = dst->format->BytesPerPixel;
00084 p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00085 switch (bpp) {
00086 case 1:
00087 *p = color;
00088 break;
00089 case 2:
00090 *(Uint16 *) p = color;
00091 break;
00092 case 3:
00093 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00094 p[0] = (color >> 16) & 0xff;
00095 p[1] = (color >> 8) & 0xff;
00096 p[2] = color & 0xff;
00097 } else {
00098 p[0] = color & 0xff;
00099 p[1] = (color >> 8) & 0xff;
00100 p[2] = (color >> 16) & 0xff;
00101 }
00102 break;
00103 case 4:
00104 *(Uint32 *) p = color;
00105 break;
00106 }
00107
00108 return (0);
00109 }
00110
00111
00112
00113 int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00114 {
00115 int result;
00116
00117
00118
00119
00120 if (SDL_MUSTLOCK(dst)) {
00121 if (SDL_LockSurface(dst) < 0) {
00122 return (-1);
00123 }
00124 }
00125
00126 result = fastPixelColorNolock(dst, x, y, color);
00127
00128
00129
00130
00131 if (SDL_MUSTLOCK(dst)) {
00132 SDL_UnlockSurface(dst);
00133 }
00134
00135 return (result);
00136 }
00137
00138
00139
00140 int fastPixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00141 {
00142 Uint32 color;
00143
00144
00145
00146
00147 color = SDL_MapRGBA(dst->format, r, g, b, a);
00148
00149
00150
00151
00152 return (fastPixelColor(dst, x, y, color));
00153
00154 }
00155
00156
00157
00158 int fastPixelRGBANolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00159 {
00160 Uint32 color;
00161
00162
00163
00164
00165 color = SDL_MapRGBA(dst->format, r, g, b, a);
00166
00167
00168
00169
00170 return (fastPixelColorNolock(dst, x, y, color));
00171 }
00172
00173
00174
00175
00176
00177 int _putPixelAlpha(SDL_Surface * surface, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
00178 {
00179 Uint32 Rmask = surface->format->Rmask, Gmask =
00180 surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
00181 Uint32 R, G, B, A = 0;
00182
00183 if (x >= clip_xmin(surface) && x <= clip_xmax(surface)
00184 && y >= clip_ymin(surface) && y <= clip_ymax(surface)) {
00185
00186 switch (surface->format->BytesPerPixel) {
00187 case 1:{
00188 if (alpha == 255) {
00189 *((Uint8 *) surface->pixels + y * surface->pitch + x) = color;
00190 } else {
00191 Uint8 *pixel = (Uint8 *) surface->pixels + y * surface->pitch + x;
00192
00193 Uint8 dR = surface->format->palette->colors[*pixel].r;
00194 Uint8 dG = surface->format->palette->colors[*pixel].g;
00195 Uint8 dB = surface->format->palette->colors[*pixel].b;
00196 Uint8 sR = surface->format->palette->colors[color].r;
00197 Uint8 sG = surface->format->palette->colors[color].g;
00198 Uint8 sB = surface->format->palette->colors[color].b;
00199
00200 dR = dR + ((sR - dR) * alpha >> 8);
00201 dG = dG + ((sG - dG) * alpha >> 8);
00202 dB = dB + ((sB - dB) * alpha >> 8);
00203
00204 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
00205 }
00206 }
00207 break;
00208
00209 case 2:{
00210 if (alpha == 255) {
00211 *((Uint16 *) surface->pixels + y * surface->pitch / 2 + x) = color;
00212 } else {
00213 Uint16 *pixel = (Uint16 *) surface->pixels + y * surface->pitch / 2 + x;
00214 Uint32 dc = *pixel;
00215
00216 R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00217 G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00218 B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00219 if (Amask)
00220 A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
00221
00222 *pixel = R | G | B | A;
00223 }
00224 }
00225 break;
00226
00227 case 3:{
00228 Uint8 *pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3;
00229 Uint8 rshift8 = surface->format->Rshift / 8;
00230 Uint8 gshift8 = surface->format->Gshift / 8;
00231 Uint8 bshift8 = surface->format->Bshift / 8;
00232 Uint8 ashift8 = surface->format->Ashift / 8;
00233
00234
00235 if (alpha == 255) {
00236 *(pix + rshift8) = color >> surface->format->Rshift;
00237 *(pix + gshift8) = color >> surface->format->Gshift;
00238 *(pix + bshift8) = color >> surface->format->Bshift;
00239 *(pix + ashift8) = color >> surface->format->Ashift;
00240 } else {
00241 Uint8 dR, dG, dB, dA = 0;
00242 Uint8 sR, sG, sB, sA = 0;
00243
00244 pix = (Uint8 *) surface->pixels + y * surface->pitch + x * 3;
00245
00246 dR = *((pix) + rshift8);
00247 dG = *((pix) + gshift8);
00248 dB = *((pix) + bshift8);
00249 dA = *((pix) + ashift8);
00250
00251 sR = (color >> surface->format->Rshift) & 0xff;
00252 sG = (color >> surface->format->Gshift) & 0xff;
00253 sB = (color >> surface->format->Bshift) & 0xff;
00254 sA = (color >> surface->format->Ashift) & 0xff;
00255
00256 dR = dR + ((sR - dR) * alpha >> 8);
00257 dG = dG + ((sG - dG) * alpha >> 8);
00258 dB = dB + ((sB - dB) * alpha >> 8);
00259 dA = dA + ((sA - dA) * alpha >> 8);
00260
00261 *((pix) + rshift8) = dR;
00262 *((pix) + gshift8) = dG;
00263 *((pix) + bshift8) = dB;
00264 *((pix) + ashift8) = dA;
00265 }
00266 }
00267 break;
00268
00269 case 4:{
00270 if (alpha == 255) {
00271 *((Uint32 *) surface->pixels + y * surface->pitch / 4 + x) = color;
00272 } else {
00273 Uint32 *pixel = (Uint32 *) surface->pixels + y * surface->pitch / 4 + x;
00274 Uint32 dc = *pixel;
00275
00276 R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00277 G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00278 B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00279 if (Amask)
00280 A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
00281
00282 *pixel = R | G | B | A;
00283 }
00284 }
00285 break;
00286 }
00287 }
00288
00289 return (0);
00290 }
00291
00292
00293
00294 int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00295 {
00296 Uint8 alpha;
00297 Uint32 mcolor;
00298 int result = 0;
00299
00300
00301
00302
00303 if (SDL_MUSTLOCK(dst)) {
00304 if (SDL_LockSurface(dst) < 0) {
00305 return (-1);
00306 }
00307 }
00308
00309
00310
00311
00312 alpha = color & 0x000000ff;
00313 mcolor =
00314 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00315 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00316
00317
00318
00319
00320 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
00321
00322
00323
00324
00325 if (SDL_MUSTLOCK(dst)) {
00326 SDL_UnlockSurface(dst);
00327 }
00328
00329 return (result);
00330 }
00331
00332 int pixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00333 {
00334 Uint8 alpha;
00335 Uint32 mcolor;
00336 int result = 0;
00337
00338
00339
00340
00341 alpha = color & 0x000000ff;
00342 mcolor =
00343 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00344 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00345
00346
00347
00348
00349 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
00350
00351 return (result);
00352 }
00353
00354
00355
00356
00357 int _filledRectAlpha(SDL_Surface * surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
00358 {
00359 Uint32 Rmask = surface->format->Rmask, Gmask =
00360 surface->format->Gmask, Bmask = surface->format->Bmask, Amask = surface->format->Amask;
00361 Uint32 R, G, B, A = 0;
00362 Sint16 x, y;
00363
00364 switch (surface->format->BytesPerPixel) {
00365 case 1:{
00366 Uint8 *row, *pixel;
00367 Uint8 dR, dG, dB;
00368
00369 Uint8 sR = surface->format->palette->colors[color].r;
00370 Uint8 sG = surface->format->palette->colors[color].g;
00371 Uint8 sB = surface->format->palette->colors[color].b;
00372
00373 for (y = y1; y <= y2; y++) {
00374 row = (Uint8 *) surface->pixels + y * surface->pitch;
00375 for (x = x1; x <= x2; x++) {
00376 pixel = row + x;
00377
00378 dR = surface->format->palette->colors[*pixel].r;
00379 dG = surface->format->palette->colors[*pixel].g;
00380 dB = surface->format->palette->colors[*pixel].b;
00381
00382 dR = dR + ((sR - dR) * alpha >> 8);
00383 dG = dG + ((sG - dG) * alpha >> 8);
00384 dB = dB + ((sB - dB) * alpha >> 8);
00385
00386 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
00387 }
00388 }
00389 }
00390 break;
00391
00392 case 2:{
00393 Uint16 *row, *pixel;
00394 Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
00395
00396 for (y = y1; y <= y2; y++) {
00397 row = (Uint16 *) surface->pixels + y * surface->pitch / 2;
00398 for (x = x1; x <= x2; x++) {
00399 pixel = row + x;
00400
00401 R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
00402 G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
00403 B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
00404 if (Amask)
00405 A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
00406
00407 *pixel = R | G | B | A;
00408 }
00409 }
00410 }
00411 break;
00412
00413 case 3:{
00414 Uint8 *row, *pix;
00415 Uint8 dR, dG, dB, dA;
00416 Uint8 rshift8 = surface->format->Rshift / 8;
00417 Uint8 gshift8 = surface->format->Gshift / 8;
00418 Uint8 bshift8 = surface->format->Bshift / 8;
00419 Uint8 ashift8 = surface->format->Ashift / 8;
00420
00421 Uint8 sR = (color >> surface->format->Rshift) & 0xff;
00422 Uint8 sG = (color >> surface->format->Gshift) & 0xff;
00423 Uint8 sB = (color >> surface->format->Bshift) & 0xff;
00424 Uint8 sA = (color >> surface->format->Ashift) & 0xff;
00425
00426 for (y = y1; y <= y2; y++) {
00427 row = (Uint8 *) surface->pixels + y * surface->pitch;
00428 for (x = x1; x <= x2; x++) {
00429 pix = row + x * 3;
00430
00431 dR = *((pix) + rshift8);
00432 dG = *((pix) + gshift8);
00433 dB = *((pix) + bshift8);
00434 dA = *((pix) + ashift8);
00435
00436 dR = dR + ((sR - dR) * alpha >> 8);
00437 dG = dG + ((sG - dG) * alpha >> 8);
00438 dB = dB + ((sB - dB) * alpha >> 8);
00439 dA = dA + ((sA - dA) * alpha >> 8);
00440
00441 *((pix) + rshift8) = dR;
00442 *((pix) + gshift8) = dG;
00443 *((pix) + bshift8) = dB;
00444 *((pix) + ashift8) = dA;
00445 }
00446 }
00447
00448 }
00449 break;
00450
00451 case 4:{
00452 Uint32 *row, *pixel;
00453 Uint32 dR = (color & Rmask), dG = (color & Gmask), dB = (color & Bmask), dA = (color & Amask);
00454
00455 for (y = y1; y <= y2; y++) {
00456 row = (Uint32 *) surface->pixels + y * surface->pitch / 4;
00457 for (x = x1; x <= x2; x++) {
00458 pixel = row + x;
00459
00460 R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
00461 G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
00462 B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
00463 if (Amask)
00464 A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
00465
00466 *pixel = R | G | B | A;
00467 }
00468 }
00469 }
00470 break;
00471 }
00472
00473 return (0);
00474 }
00475
00476
00477
00478 int filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
00479 {
00480 Uint8 alpha;
00481 Uint32 mcolor;
00482 int result = 0;
00483
00484
00485
00486
00487 if (SDL_MUSTLOCK(dst)) {
00488 if (SDL_LockSurface(dst) < 0) {
00489 return (-1);
00490 }
00491 }
00492
00493
00494
00495
00496 alpha = color & 0x000000ff;
00497 mcolor =
00498 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00499 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00500
00501
00502
00503
00504 result = _filledRectAlpha(dst, x1, y1, x2, y2, mcolor, alpha);
00505
00506
00507
00508
00509 if (SDL_MUSTLOCK(dst)) {
00510 SDL_UnlockSurface(dst);
00511 }
00512
00513 return (result);
00514 }
00515
00516
00517
00518 int HLineAlpha(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
00519 {
00520 return (filledRectAlpha(dst, x1, y, x2, y, color));
00521 }
00522
00523
00524
00525
00526 int VLineAlpha(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
00527 {
00528 return (filledRectAlpha(dst, x, y1, x, y2, color));
00529 }
00530
00531
00532
00533
00534 int pixelColorWeight(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
00535 {
00536 Uint32 a;
00537
00538
00539
00540
00541 a = (color & (Uint32) 0x000000ff);
00542
00543
00544
00545
00546 a = ((a * weight) >> 8);
00547
00548 return (pixelColor(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
00549 }
00550
00551
00552
00553 int pixelColorWeightNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
00554 {
00555 Uint32 a;
00556
00557
00558
00559
00560 a = (color & (Uint32) 0x000000ff);
00561
00562
00563
00564
00565 a = ((a * weight) >> 8);
00566
00567 return (pixelColorNolock(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
00568 }
00569
00570 int pixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00571 {
00572 Uint32 color;
00573
00574
00575
00576
00577 if (a == 255) {
00578
00579
00580
00581
00582
00583
00584 color = SDL_MapRGBA(dst->format, r, g, b, a);
00585
00586
00587
00588 return (fastPixelColor(dst, x, y, color));
00589 } else {
00590
00591
00592
00593
00594
00595
00596 return (pixelColor(dst, x, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
00597 }
00598 }
00599
00600
00601
00602
00603
00604 int hlineColorStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
00605 {
00606 Sint16 left, right, top, bottom;
00607 Uint8 *pixel, *pixellast;
00608 int dx;
00609 int pixx, pixy;
00610 Sint16 w;
00611 Sint16 xtmp;
00612 int result = -1;
00613
00614
00615
00616
00617 left = dst->clip_rect.x;
00618 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00619 top = dst->clip_rect.y;
00620 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00621
00622
00623
00624
00625 if ((x1<left) && (x2<left)) {
00626 return(0);
00627 }
00628 if ((x1>right) && (x2>right)) {
00629 return(0);
00630 }
00631 if ((y<top) || (y>bottom)) {
00632 return (0);
00633 }
00634
00635
00636
00637
00638 if (x1 < left) {
00639 x1 = left;
00640 }
00641 if (x2 > right) {
00642 x2 = right;
00643 }
00644
00645
00646
00647
00648 if (x1 > x2) {
00649 xtmp = x1;
00650 x1 = x2;
00651 x2 = xtmp;
00652 }
00653
00654
00655
00656
00657 w = x2 - x1;
00658
00659
00660
00661
00662 if (w < 0) {
00663 return (0);
00664 }
00665
00666
00667
00668
00669 SDL_LockSurface(dst);
00670
00671
00672
00673
00674 dx = w;
00675 pixx = dst->format->BytesPerPixel;
00676 pixy = dst->pitch;
00677 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
00678
00679
00680
00681
00682 switch (dst->format->BytesPerPixel) {
00683 case 1:
00684 memset(pixel, color, dx);
00685 break;
00686 case 2:
00687 pixellast = pixel + dx + dx;
00688 for (; pixel <= pixellast; pixel += pixx) {
00689 *(Uint16 *) pixel = color;
00690 }
00691 break;
00692 case 3:
00693 pixellast = pixel + dx + dx + dx;
00694 for (; pixel <= pixellast; pixel += pixx) {
00695 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00696 pixel[0] = (color >> 16) & 0xff;
00697 pixel[1] = (color >> 8) & 0xff;
00698 pixel[2] = color & 0xff;
00699 } else {
00700 pixel[0] = color & 0xff;
00701 pixel[1] = (color >> 8) & 0xff;
00702 pixel[2] = (color >> 16) & 0xff;
00703 }
00704 }
00705 break;
00706 default:
00707 dx = dx + dx;
00708 pixellast = pixel + dx + dx;
00709 for (; pixel <= pixellast; pixel += pixx) {
00710 *(Uint32 *) pixel = color;
00711 }
00712 break;
00713 }
00714
00715
00716
00717
00718 SDL_UnlockSurface(dst);
00719
00720
00721
00722
00723 result = 0;
00724
00725 return (result);
00726 }
00727
00728 int hlineRGBAStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00729 {
00730
00731
00732
00733 return (hlineColorStore(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
00734 }
00735
00736 int hlineColor(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
00737 {
00738 Sint16 left, right, top, bottom;
00739 Uint8 *pixel, *pixellast;
00740 int dx;
00741 int pixx, pixy;
00742 Sint16 w;
00743 Sint16 xtmp;
00744 int result = -1;
00745 Uint8 *colorptr;
00746
00747
00748
00749
00750 left = dst->clip_rect.x;
00751 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00752 top = dst->clip_rect.y;
00753 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00754
00755
00756
00757
00758 if ((x1<left) && (x2<left)) {
00759 return(0);
00760 }
00761 if ((x1>right) && (x2>right)) {
00762 return(0);
00763 }
00764 if ((y<top) || (y>bottom)) {
00765 return (0);
00766 }
00767
00768
00769
00770
00771 if (x1 < left) {
00772 x1 = left;
00773 }
00774 if (x2 > right) {
00775 x2 = right;
00776 }
00777
00778
00779
00780
00781 if (x1 > x2) {
00782 xtmp = x1;
00783 x1 = x2;
00784 x2 = xtmp;
00785 }
00786
00787
00788
00789
00790 w = x2 - x1;
00791
00792
00793
00794
00795 if (w < 0) {
00796 return (0);
00797 }
00798
00799
00800
00801
00802 if ((color & 255) == 255) {
00803
00804
00805
00806
00807
00808
00809
00810
00811 colorptr = (Uint8 *) & color;
00812 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00813 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
00814 } else {
00815 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
00816 }
00817
00818
00819
00820
00821 SDL_LockSurface(dst);
00822
00823
00824
00825
00826 dx = w;
00827 pixx = dst->format->BytesPerPixel;
00828 pixy = dst->pitch;
00829 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
00830
00831
00832
00833
00834 switch (dst->format->BytesPerPixel) {
00835 case 1:
00836 memset(pixel, color, dx);
00837 break;
00838 case 2:
00839 pixellast = pixel + dx + dx;
00840 for (; pixel <= pixellast; pixel += pixx) {
00841 *(Uint16 *) pixel = color;
00842 }
00843 break;
00844 case 3:
00845 pixellast = pixel + dx + dx + dx;
00846 for (; pixel <= pixellast; pixel += pixx) {
00847 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00848 pixel[0] = (color >> 16) & 0xff;
00849 pixel[1] = (color >> 8) & 0xff;
00850 pixel[2] = color & 0xff;
00851 } else {
00852 pixel[0] = color & 0xff;
00853 pixel[1] = (color >> 8) & 0xff;
00854 pixel[2] = (color >> 16) & 0xff;
00855 }
00856 }
00857 break;
00858 default:
00859 dx = dx + dx;
00860 pixellast = pixel + dx + dx;
00861 for (; pixel <= pixellast; pixel += pixx) {
00862 *(Uint32 *) pixel = color;
00863 }
00864 break;
00865 }
00866
00867
00868
00869
00870 SDL_UnlockSurface(dst);
00871
00872
00873
00874
00875 result = 0;
00876
00877 } else {
00878
00879
00880
00881
00882
00883 result = HLineAlpha(dst, x1, x1 + w, y, color);
00884
00885 }
00886
00887 return (result);
00888 }
00889
00890 int hlineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00891 {
00892
00893
00894
00895 return (hlineColor(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
00896 }
00897
00898
00899
00900 int vlineColor(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
00901 {
00902 Sint16 left, right, top, bottom;
00903 Uint8 *pixel, *pixellast;
00904 int dy;
00905 int pixx, pixy;
00906 Sint16 h;
00907 Sint16 ytmp;
00908 int result = -1;
00909 Uint8 *colorptr;
00910
00911
00912
00913
00914 left = dst->clip_rect.x;
00915 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00916 top = dst->clip_rect.y;
00917 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00918
00919
00920
00921
00922 if ((x<left) || (x>right)) {
00923 return (0);
00924 }
00925 if ((y1<top) && (y2<top)) {
00926 return(0);
00927 }
00928 if ((y1>bottom) && (y2>bottom)) {
00929 return(0);
00930 }
00931
00932
00933
00934
00935 if (y1 < top) {
00936 y1 = top;
00937 }
00938 if (y2 > bottom) {
00939 y2 = bottom;
00940 }
00941
00942
00943
00944
00945 if (y1 > y2) {
00946 ytmp = y1;
00947 y1 = y2;
00948 y2 = ytmp;
00949 }
00950
00951
00952
00953
00954 h = y2 - y1;
00955
00956
00957
00958
00959 if (h < 0) {
00960 return (0);
00961 }
00962
00963
00964
00965
00966 if ((color & 255) == 255) {
00967
00968
00969
00970
00971
00972
00973
00974
00975 colorptr = (Uint8 *) & color;
00976 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00977 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
00978 } else {
00979 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
00980 }
00981
00982
00983
00984
00985 SDL_LockSurface(dst);
00986
00987
00988
00989
00990 dy = h;
00991 pixx = dst->format->BytesPerPixel;
00992 pixy = dst->pitch;
00993 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x + pixy * (int) y1;
00994 pixellast = pixel + pixy * dy;
00995
00996
00997
00998
00999 switch (dst->format->BytesPerPixel) {
01000 case 1:
01001 for (; pixel <= pixellast; pixel += pixy) {
01002 *(Uint8 *) pixel = color;
01003 }
01004 break;
01005 case 2:
01006 for (; pixel <= pixellast; pixel += pixy) {
01007 *(Uint16 *) pixel = color;
01008 }
01009 break;
01010 case 3:
01011 for (; pixel <= pixellast; pixel += pixy) {
01012 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01013 pixel[0] = (color >> 16) & 0xff;
01014 pixel[1] = (color >> 8) & 0xff;
01015 pixel[2] = color & 0xff;
01016 } else {
01017 pixel[0] = color & 0xff;
01018 pixel[1] = (color >> 8) & 0xff;
01019 pixel[2] = (color >> 16) & 0xff;
01020 }
01021 }
01022 break;
01023 default:
01024 for (; pixel <= pixellast; pixel += pixy) {
01025 *(Uint32 *) pixel = color;
01026 }
01027 break;
01028 }
01029
01030
01031
01032
01033 SDL_UnlockSurface(dst);
01034
01035
01036
01037
01038 result = 0;
01039
01040 } else {
01041
01042
01043
01044
01045
01046 result = VLineAlpha(dst, x, y1, y1 + h, color);
01047
01048 }
01049
01050 return (result);
01051 }
01052
01053 int vlineRGBA(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01054 {
01055
01056
01057
01058 return (vlineColor(dst, x, y1, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01059 }
01060
01061
01062
01063 int rectangleColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01064 {
01065 int result;
01066 Sint16 w, h, xtmp, ytmp;
01067
01068
01069
01070
01071 if (x1 > x2) {
01072 xtmp = x1;
01073 x1 = x2;
01074 x2 = xtmp;
01075 }
01076
01077
01078
01079
01080 if (y1 > y2) {
01081 ytmp = y1;
01082 y1 = y2;
01083 y2 = ytmp;
01084 }
01085
01086
01087
01088
01089 w = x2 - x1;
01090 h = y2 - y1;
01091
01092
01093
01094
01095 if ((w < 0) || (h < 0)) {
01096 return (0);
01097 }
01098
01099
01100
01101
01102 if (x1 == x2) {
01103 if (y1 == y2) {
01104 return (pixelColor(dst, x1, y1, color));
01105 } else {
01106 return (vlineColor(dst, x1, y1, y2, color));
01107 }
01108 } else {
01109 if (y1 == y2) {
01110 return (hlineColor(dst, x1, x2, y1, color));
01111 }
01112 }
01113
01114
01115
01116
01117 result = 0;
01118 result |= hlineColor(dst, x1, x2, y1, color);
01119 result |= hlineColor(dst, x1, x2, y2, color);
01120 y1 += 1;
01121 y2 -= 1;
01122 if (y1<=y2) {
01123 result |= vlineColor(dst, x1, y1, y2, color);
01124 result |= vlineColor(dst, x2, y1, y2, color);
01125 }
01126 return (result);
01127
01128 }
01129
01130 int rectangleRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01131 {
01132
01133
01134
01135 return (rectangleColor
01136 (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01137 }
01138
01139
01140
01141
01142
01143
01144 #define CLIP_LEFT_EDGE 0x1
01145 #define CLIP_RIGHT_EDGE 0x2
01146 #define CLIP_BOTTOM_EDGE 0x4
01147 #define CLIP_TOP_EDGE 0x8
01148 #define CLIP_INSIDE(a) (!a)
01149 #define CLIP_REJECT(a,b) (a&b)
01150 #define CLIP_ACCEPT(a,b) (!(a|b))
01151
01152 static int clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
01153 {
01154 int code = 0;
01155
01156 if (x < left) {
01157 code |= CLIP_LEFT_EDGE;
01158 } else if (x > right) {
01159 code |= CLIP_RIGHT_EDGE;
01160 }
01161 if (y < top) {
01162 code |= CLIP_TOP_EDGE;
01163 } else if (y > bottom) {
01164 code |= CLIP_BOTTOM_EDGE;
01165 }
01166 return code;
01167 }
01168
01169 static int clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2)
01170 {
01171 Sint16 left, right, top, bottom;
01172 int code1, code2;
01173 int draw = 0;
01174 Sint16 swaptmp;
01175 float m;
01176
01177
01178
01179
01180 left = dst->clip_rect.x;
01181 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01182 top = dst->clip_rect.y;
01183 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01184
01185 while (1) {
01186 code1 = clipEncode(*x1, *y1, left, top, right, bottom);
01187 code2 = clipEncode(*x2, *y2, left, top, right, bottom);
01188 if (CLIP_ACCEPT(code1, code2)) {
01189 draw = 1;
01190 break;
01191 } else if (CLIP_REJECT(code1, code2))
01192 break;
01193 else {
01194 if (CLIP_INSIDE(code1)) {
01195 swaptmp = *x2;
01196 *x2 = *x1;
01197 *x1 = swaptmp;
01198 swaptmp = *y2;
01199 *y2 = *y1;
01200 *y1 = swaptmp;
01201 swaptmp = code2;
01202 code2 = code1;
01203 code1 = swaptmp;
01204 }
01205 if (*x2 != *x1) {
01206 m = (*y2 - *y1) / (float) (*x2 - *x1);
01207 } else {
01208 m = 1.0f;
01209 }
01210 if (code1 & CLIP_LEFT_EDGE) {
01211 *y1 += (Sint16) ((left - *x1) * m);
01212 *x1 = left;
01213 } else if (code1 & CLIP_RIGHT_EDGE) {
01214 *y1 += (Sint16) ((right - *x1) * m);
01215 *x1 = right;
01216 } else if (code1 & CLIP_BOTTOM_EDGE) {
01217 if (*x2 != *x1) {
01218 *x1 += (Sint16) ((bottom - *y1) / m);
01219 }
01220 *y1 = bottom;
01221 } else if (code1 & CLIP_TOP_EDGE) {
01222 if (*x2 != *x1) {
01223 *x1 += (Sint16) ((top - *y1) / m);
01224 }
01225 *y1 = top;
01226 }
01227 }
01228 }
01229
01230 return draw;
01231 }
01232
01233
01234
01235 int boxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01236 {
01237 Sint16 left, right, top, bottom;
01238 Uint8 *pixel, *pixellast;
01239 int x, dx;
01240 int dy;
01241 int pixx, pixy;
01242 Sint16 w, h, tmp;
01243 int result;
01244 Uint8 *colorptr;
01245
01246
01247
01248
01249 left = dst->clip_rect.x;
01250 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01251 top = dst->clip_rect.y;
01252 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01253
01254
01255 if ((x1<left) && (x2<left)) {
01256 return(0);
01257 }
01258 if ((x1>right) && (x2>right)) {
01259 return(0);
01260 }
01261 if ((y1<top) && (y2<top)) {
01262 return(0);
01263 }
01264 if ((y1>bottom) && (y2>bottom)) {
01265 return(0);
01266 }
01267
01268
01269 if (x1<left) {
01270 x1=left;
01271 } else if (x1>right) {
01272 x1=right;
01273 }
01274 if (x2<left) {
01275 x2=left;
01276 } else if (x2>right) {
01277 x2=right;
01278 }
01279 if (y1<top) {
01280 y1=top;
01281 } else if (y1>bottom) {
01282 y1=bottom;
01283 }
01284 if (y2<top) {
01285 y2=top;
01286 } else if (y2>bottom) {
01287 y2=bottom;
01288 }
01289
01290
01291
01292
01293 if (x1 > x2) {
01294 tmp = x1;
01295 x1 = x2;
01296 x2 = tmp;
01297 }
01298 if (y1 > y2) {
01299 tmp = y1;
01300 y1 = y2;
01301 y2 = tmp;
01302 }
01303
01304
01305
01306
01307 if (x1 == x2) {
01308 if (y1 == y2) {
01309 return (pixelColor(dst, x1, y1, color));
01310 } else {
01311 return (vlineColor(dst, x1, y1, y2, color));
01312 }
01313 }
01314 if (y1 == y2) {
01315 return (hlineColor(dst, x1, x2, y1, color));
01316 }
01317
01318
01319
01320
01321
01322 w = x2 - x1;
01323 h = y2 - y1;
01324
01325
01326
01327
01328 if ((color & 255) == 255) {
01329
01330
01331
01332
01333
01334
01335
01336
01337 colorptr = (Uint8 *) & color;
01338 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01339 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01340 } else {
01341 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01342 }
01343
01344
01345
01346
01347 SDL_LockSurface(dst);
01348
01349
01350
01351
01352 dx = w;
01353 dy = h;
01354 pixx = dst->format->BytesPerPixel;
01355 pixy = dst->pitch;
01356 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
01357 pixellast = pixel + pixx * dx + pixy * dy;
01358 dx++;
01359
01360
01361
01362
01363 switch (dst->format->BytesPerPixel) {
01364 case 1:
01365 for (; pixel <= pixellast; pixel += pixy) {
01366 memset(pixel, (Uint8) color, dx);
01367 }
01368 break;
01369 case 2:
01370 pixy -= (pixx * dx);
01371 for (; pixel <= pixellast; pixel += pixy) {
01372 for (x = 0; x < dx; x++) {
01373 *(Uint16 *) pixel = color;
01374 pixel += pixx;
01375 }
01376 }
01377 break;
01378 case 3:
01379 pixy -= (pixx * dx);
01380 for (; pixel <= pixellast; pixel += pixy) {
01381 for (x = 0; x < dx; x++) {
01382 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01383 pixel[0] = (color >> 16) & 0xff;
01384 pixel[1] = (color >> 8) & 0xff;
01385 pixel[2] = color & 0xff;
01386 } else {
01387 pixel[0] = color & 0xff;
01388 pixel[1] = (color >> 8) & 0xff;
01389 pixel[2] = (color >> 16) & 0xff;
01390 }
01391 pixel += pixx;
01392 }
01393 }
01394 break;
01395 default:
01396 pixy -= (pixx * dx);
01397 for (; pixel <= pixellast; pixel += pixy) {
01398 for (x = 0; x < dx; x++) {
01399 *(Uint32 *) pixel = color;
01400 pixel += pixx;
01401 }
01402 }
01403 break;
01404 }
01405
01406
01407
01408
01409 SDL_UnlockSurface(dst);
01410
01411 result = 0;
01412
01413 } else {
01414
01415 result = filledRectAlpha(dst, x1, y1, x1 + w, y1 + h, color);
01416
01417 }
01418
01419 return (result);
01420 }
01421
01422 int boxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01423 {
01424
01425
01426
01427 return (boxColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01428 }
01429
01430
01431
01432
01433
01434
01435
01436 #define ABS(a) (((a)<0) ? -(a) : (a))
01437
01438 int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01439 {
01440 int pixx, pixy;
01441 int x, y;
01442 int dx, dy;
01443 int ax, ay;
01444 int sx, sy;
01445 int swaptmp;
01446 Uint8 *pixel;
01447 Uint8 *colorptr;
01448
01449
01450
01451
01452 if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
01453 return (0);
01454 }
01455
01456
01457
01458
01459 if (x1 == x2) {
01460 if (y1 < y2) {
01461 return (vlineColor(dst, x1, y1, y2, color));
01462 } else if (y1 > y2) {
01463 return (vlineColor(dst, x1, y2, y1, color));
01464 } else {
01465 return (pixelColor(dst, x1, y1, color));
01466 }
01467 }
01468 if (y1 == y2) {
01469 if (x1 < x2) {
01470 return (hlineColor(dst, x1, x2, y1, color));
01471 } else if (x1 > x2) {
01472 return (hlineColor(dst, x2, x1, y1, color));
01473 }
01474 }
01475
01476
01477
01478
01479 dx = x2 - x1;
01480 dy = y2 - y1;
01481 sx = (dx >= 0) ? 1 : -1;
01482 sy = (dy >= 0) ? 1 : -1;
01483
01484
01485 if (SDL_MUSTLOCK(dst)) {
01486 if (SDL_LockSurface(dst) < 0) {
01487 return (-1);
01488 }
01489 }
01490
01491
01492
01493
01494 if ((color & 255) == 255) {
01495
01496
01497
01498
01499
01500
01501
01502
01503 colorptr = (Uint8 *) & color;
01504 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01505 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01506 } else {
01507 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01508 }
01509
01510
01511
01512
01513 dx = sx * dx + 1;
01514 dy = sy * dy + 1;
01515 pixx = dst->format->BytesPerPixel;
01516 pixy = dst->pitch;
01517 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
01518 pixx *= sx;
01519 pixy *= sy;
01520 if (dx < dy) {
01521 swaptmp = dx;
01522 dx = dy;
01523 dy = swaptmp;
01524 swaptmp = pixx;
01525 pixx = pixy;
01526 pixy = swaptmp;
01527 }
01528
01529
01530
01531
01532 x = 0;
01533 y = 0;
01534 switch (dst->format->BytesPerPixel) {
01535 case 1:
01536 for (; x < dx; x++, pixel += pixx) {
01537 *pixel = color;
01538 y += dy;
01539 if (y >= dx) {
01540 y -= dx;
01541 pixel += pixy;
01542 }
01543 }
01544 break;
01545 case 2:
01546 for (; x < dx; x++, pixel += pixx) {
01547 *(Uint16 *) pixel = color;
01548 y += dy;
01549 if (y >= dx) {
01550 y -= dx;
01551 pixel += pixy;
01552 }
01553 }
01554 break;
01555 case 3:
01556 for (; x < dx; x++, pixel += pixx) {
01557 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01558 pixel[0] = (color >> 16) & 0xff;
01559 pixel[1] = (color >> 8) & 0xff;
01560 pixel[2] = color & 0xff;
01561 } else {
01562 pixel[0] = color & 0xff;
01563 pixel[1] = (color >> 8) & 0xff;
01564 pixel[2] = (color >> 16) & 0xff;
01565 }
01566 y += dy;
01567 if (y >= dx) {
01568 y -= dx;
01569 pixel += pixy;
01570 }
01571 }
01572 break;
01573 default:
01574 for (; x < dx; x++, pixel += pixx) {
01575 *(Uint32 *) pixel = color;
01576 y += dy;
01577 if (y >= dx) {
01578 y -= dx;
01579 pixel += pixy;
01580 }
01581 }
01582 break;
01583 }
01584
01585 } else {
01586
01587
01588
01589
01590
01591 ax = ABS(dx) << 1;
01592 ay = ABS(dy) << 1;
01593 x = x1;
01594 y = y1;
01595 if (ax > ay) {
01596 int d = ay - (ax >> 1);
01597
01598 while (x != x2) {
01599 pixelColorNolock (dst, x, y, color);
01600 if (d > 0 || (d == 0 && sx == 1)) {
01601 y += sy;
01602 d -= ax;
01603 }
01604 x += sx;
01605 d += ay;
01606 }
01607 } else {
01608 int d = ax - (ay >> 1);
01609
01610 while (y != y2) {
01611 pixelColorNolock (dst, x, y, color);
01612 if (d > 0 || ((d == 0) && (sy == 1))) {
01613 x += sx;
01614 d -= ay;
01615 }
01616 y += sy;
01617 d += ax;
01618 }
01619 }
01620 pixelColorNolock (dst, x, y, color);
01621
01622 }
01623
01624
01625 if (SDL_MUSTLOCK(dst)) {
01626 SDL_UnlockSurface(dst);
01627 }
01628
01629 return (0);
01630 }
01631
01632 int lineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01633 {
01634
01635
01636
01637 return (lineColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01638 }
01639
01640
01641
01642 #define AAlevels 256
01643 #define AAbits 8
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654 int aalineColorInt(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint)
01655 {
01656 Sint32 xx0, yy0, xx1, yy1;
01657 int result;
01658 Uint32 intshift, erracc, erradj;
01659 Uint32 erracctmp, wgt, wgtcompmask;
01660 int dx, dy, tmp, xdir, y0p1, x0pxdir;
01661
01662
01663
01664
01665 if (!(clipLine(dst, &x1, &y1, &x2, &y2))) {
01666 return (0);
01667 }
01668
01669
01670
01671
01672 xx0 = x1;
01673 yy0 = y1;
01674 xx1 = x2;
01675 yy1 = y2;
01676
01677
01678
01679
01680 if (yy0 > yy1) {
01681 tmp = yy0;
01682 yy0 = yy1;
01683 yy1 = tmp;
01684 tmp = xx0;
01685 xx0 = xx1;
01686 xx1 = tmp;
01687 }
01688
01689
01690
01691
01692 dx = xx1 - xx0;
01693 dy = yy1 - yy0;
01694
01695
01696
01697
01698 if (dx >= 0) {
01699 xdir = 1;
01700 } else {
01701 xdir = -1;
01702 dx = (-dx);
01703 }
01704
01705
01706
01707
01708 if (dx == 0) {
01709
01710
01711
01712 return (vlineColor(dst, x1, y1, y2, color));
01713 } else if (dy == 0) {
01714
01715
01716
01717 return (hlineColor(dst, x1, x2, y1, color));
01718 } else if (dx == dy) {
01719
01720
01721
01722 return (lineColor(dst, x1, y1, x2, y2, color));
01723 }
01724
01725
01726
01727
01728 result = 0;
01729
01730
01731
01732
01733 erracc = 0;
01734
01735
01736
01737
01738 intshift = 32 - AAbits;
01739
01740
01741
01742 wgtcompmask = AAlevels - 1;
01743
01744
01745 if (SDL_MUSTLOCK(dst)) {
01746 if (SDL_LockSurface(dst) < 0) {
01747 return (-1);
01748 }
01749 }
01750
01751
01752
01753
01754 result |= pixelColorNolock(dst, x1, y1, color);
01755
01756
01757
01758
01759 if (dy > dx) {
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769 erradj = ((dx << 16) / dy) << 16;
01770
01771
01772
01773
01774 x0pxdir = xx0 + xdir;
01775 while (--dy) {
01776 erracctmp = erracc;
01777 erracc += erradj;
01778 if (erracc <= erracctmp) {
01779
01780
01781
01782 xx0 = x0pxdir;
01783 x0pxdir += xdir;
01784 }
01785 yy0++;
01786
01787
01788
01789
01790
01791
01792 wgt = (erracc >> intshift) & 255;
01793 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
01794 result |= pixelColorWeightNolock (dst, x0pxdir, yy0, color, wgt);
01795 }
01796
01797 } else {
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807 erradj = ((dy << 16) / dx) << 16;
01808
01809
01810
01811
01812 y0p1 = yy0 + 1;
01813 while (--dx) {
01814
01815 erracctmp = erracc;
01816 erracc += erradj;
01817 if (erracc <= erracctmp) {
01818
01819
01820
01821 yy0 = y0p1;
01822 y0p1++;
01823 }
01824 xx0 += xdir;
01825
01826
01827
01828
01829
01830 wgt = (erracc >> intshift) & 255;
01831 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
01832 result |= pixelColorWeightNolock (dst, xx0, y0p1, color, wgt);
01833 }
01834 }
01835
01836
01837
01838
01839 if (draw_endpoint) {
01840
01841
01842
01843
01844 result |= pixelColorNolock (dst, x2, y2, color);
01845 }
01846
01847
01848 if (SDL_MUSTLOCK(dst)) {
01849 SDL_UnlockSurface(dst);
01850 }
01851
01852 return (result);
01853 }
01854
01855 int aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01856 {
01857 return (aalineColorInt(dst, x1, y1, x2, y2, color, 1));
01858 }
01859
01860 int aalineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01861 {
01862 return (aalineColorInt
01863 (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
01864 }
01865
01866
01867
01868
01869
01870
01871
01872 int circleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
01873 {
01874 Sint16 left, right, top, bottom;
01875 int result;
01876 Sint16 x1, y1, x2, y2;
01877 Sint16 cx = 0;
01878 Sint16 cy = r;
01879 Sint16 ocx = (Sint16) 0xffff;
01880 Sint16 ocy = (Sint16) 0xffff;
01881 Sint16 df = 1 - r;
01882 Sint16 d_e = 3;
01883 Sint16 d_se = -2 * r + 5;
01884 Sint16 xpcx, xmcx, xpcy, xmcy;
01885 Sint16 ypcy, ymcy, ypcx, ymcx;
01886 Uint8 *colorptr;
01887
01888
01889
01890
01891 if (r < 0) {
01892 return (-1);
01893 }
01894
01895
01896
01897
01898 if (r == 0) {
01899 return (pixelColor(dst, x, y, color));
01900 }
01901
01902
01903
01904
01905 left = dst->clip_rect.x;
01906 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01907 top = dst->clip_rect.y;
01908 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01909
01910
01911
01912
01913 x1 = x - r;
01914 x2 = x + r;
01915 y1 = y - r;
01916 y2 = y + r;
01917 if ((x1<left) && (x2<left)) {
01918 return(0);
01919 }
01920 if ((x1>right) && (x2>right)) {
01921 return(0);
01922 }
01923 if ((y1<top) && (y2<top)) {
01924 return(0);
01925 }
01926 if ((y1>bottom) && (y2>bottom)) {
01927 return(0);
01928 }
01929
01930
01931
01932
01933 result = 0;
01934
01935
01936 if (SDL_MUSTLOCK(dst)) {
01937 if (SDL_LockSurface(dst) < 0) {
01938 return (-1);
01939 }
01940 }
01941
01942
01943
01944
01945 if ((color & 255) == 255) {
01946
01947
01948
01949
01950
01951
01952
01953
01954 colorptr = (Uint8 *) & color;
01955 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01956 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01957 } else {
01958 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01959 }
01960
01961
01962
01963
01964 do {
01965 if ((ocy != cy) || (ocx != cx)) {
01966 xpcx = x + cx;
01967 xmcx = x - cx;
01968 if (cy > 0) {
01969 ypcy = y + cy;
01970 ymcy = y - cy;
01971 result |= fastPixelColorNolock(dst, xmcx, ypcy, color);
01972 result |= fastPixelColorNolock(dst, xpcx, ypcy, color);
01973 result |= fastPixelColorNolock(dst, xmcx, ymcy, color);
01974 result |= fastPixelColorNolock(dst, xpcx, ymcy, color);
01975 } else {
01976 result |= fastPixelColorNolock(dst, xmcx, y, color);
01977 result |= fastPixelColorNolock(dst, xpcx, y, color);
01978 }
01979 ocy = cy;
01980 xpcy = x + cy;
01981 xmcy = x - cy;
01982 if (cx > 0) {
01983 ypcx = y + cx;
01984 ymcx = y - cx;
01985 result |= fastPixelColorNolock(dst, xmcy, ypcx, color);
01986 result |= fastPixelColorNolock(dst, xpcy, ypcx, color);
01987 result |= fastPixelColorNolock(dst, xmcy, ymcx, color);
01988 result |= fastPixelColorNolock(dst, xpcy, ymcx, color);
01989 } else {
01990 result |= fastPixelColorNolock(dst, xmcy, y, color);
01991 result |= fastPixelColorNolock(dst, xpcy, y, color);
01992 }
01993 ocx = cx;
01994 }
01995
01996
01997
01998 if (df < 0) {
01999 df += d_e;
02000 d_e += 2;
02001 d_se += 2;
02002 } else {
02003 df += d_se;
02004 d_e += 2;
02005 d_se += 4;
02006 cy--;
02007 }
02008 cx++;
02009 } while (cx <= cy);
02010
02011
02012
02013
02014 SDL_UnlockSurface(dst);
02015
02016 } else {
02017
02018
02019
02020
02021
02022 do {
02023
02024
02025
02026 if ((ocy != cy) || (ocx != cx)) {
02027 xpcx = x + cx;
02028 xmcx = x - cx;
02029 if (cy > 0) {
02030 ypcy = y + cy;
02031 ymcy = y - cy;
02032 result |= pixelColorNolock (dst, xmcx, ypcy, color);
02033 result |= pixelColorNolock (dst, xpcx, ypcy, color);
02034 result |= pixelColorNolock (dst, xmcx, ymcy, color);
02035 result |= pixelColorNolock (dst, xpcx, ymcy, color);
02036 } else {
02037 result |= pixelColorNolock (dst, xmcx, y, color);
02038 result |= pixelColorNolock (dst, xpcx, y, color);
02039 }
02040 ocy = cy;
02041 xpcy = x + cy;
02042 xmcy = x - cy;
02043 if (cx > 0) {
02044 ypcx = y + cx;
02045 ymcx = y - cx;
02046 result |= pixelColorNolock (dst, xmcy, ypcx, color);
02047 result |= pixelColorNolock (dst, xpcy, ypcx, color);
02048 result |= pixelColorNolock (dst, xmcy, ymcx, color);
02049 result |= pixelColorNolock (dst, xpcy, ymcx, color);
02050 } else {
02051 result |= pixelColorNolock (dst, xmcy, y, color);
02052 result |= pixelColorNolock (dst, xpcy, y, color);
02053 }
02054 ocx = cx;
02055 }
02056
02057
02058
02059 if (df < 0) {
02060 df += d_e;
02061 d_e += 2;
02062 d_se += 2;
02063 } else {
02064 df += d_se;
02065 d_e += 2;
02066 d_se += 4;
02067 cy--;
02068 }
02069 cx++;
02070 } while (cx <= cy);
02071
02072 }
02073
02074
02075 if (SDL_MUSTLOCK(dst)) {
02076 SDL_UnlockSurface(dst);
02077 }
02078
02079 return (result);
02080 }
02081
02082 int circleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02083 {
02084
02085
02086
02087 return (circleColor(dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02088 }
02089
02090
02091
02092
02093
02094 int aacircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
02095 {
02096 return (aaellipseColor(dst, x, y, r, r, color));
02097 }
02098
02099 int aacircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02100 {
02101
02102
02103
02104 return (aaellipseColor
02105 (dst, x, y, rad, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02106 }
02107
02108
02109
02110
02111
02112
02113
02114 int filledCircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 r, Uint32 color)
02115 {
02116 Sint16 left, right, top, bottom;
02117 int result;
02118 Sint16 x1, y1, x2, y2;
02119 Sint16 cx = 0;
02120 Sint16 cy = r;
02121 Sint16 ocx = (Sint16) 0xffff;
02122 Sint16 ocy = (Sint16) 0xffff;
02123 Sint16 df = 1 - r;
02124 Sint16 d_e = 3;
02125 Sint16 d_se = -2 * r + 5;
02126 Sint16 xpcx, xmcx, xpcy, xmcy;
02127 Sint16 ypcy, ymcy, ypcx, ymcx;
02128
02129
02130
02131
02132 if (r < 0) {
02133 return (-1);
02134 }
02135
02136
02137
02138
02139 if (r == 0) {
02140 return (pixelColor(dst, x, y, color));
02141 }
02142
02143
02144
02145
02146 left = dst->clip_rect.x;
02147 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02148 top = dst->clip_rect.y;
02149 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02150
02151
02152
02153
02154 x1 = x - r;
02155 x2 = x + r;
02156 y1 = y - r;
02157 y2 = y + r;
02158 if ((x1<left) && (x2<left)) {
02159 return(0);
02160 }
02161 if ((x1>right) && (x2>right)) {
02162 return(0);
02163 }
02164 if ((y1<top) && (y2<top)) {
02165 return(0);
02166 }
02167 if ((y1>bottom) && (y2>bottom)) {
02168 return(0);
02169 }
02170
02171
02172
02173
02174 result = 0;
02175 do {
02176 xpcx = x + cx;
02177 xmcx = x - cx;
02178 xpcy = x + cy;
02179 xmcy = x - cy;
02180 if (ocy != cy) {
02181 if (cy > 0) {
02182 ypcy = y + cy;
02183 ymcy = y - cy;
02184 result |= hlineColor(dst, xmcx, xpcx, ypcy, color);
02185 result |= hlineColor(dst, xmcx, xpcx, ymcy, color);
02186 } else {
02187 result |= hlineColor(dst, xmcx, xpcx, y, color);
02188 }
02189 ocy = cy;
02190 }
02191 if (ocx != cx) {
02192 if (cx != cy) {
02193 if (cx > 0) {
02194 ypcx = y + cx;
02195 ymcx = y - cx;
02196 result |= hlineColor(dst, xmcy, xpcy, ymcx, color);
02197 result |= hlineColor(dst, xmcy, xpcy, ypcx, color);
02198 } else {
02199 result |= hlineColor(dst, xmcy, xpcy, y, color);
02200 }
02201 }
02202 ocx = cx;
02203 }
02204
02205
02206
02207 if (df < 0) {
02208 df += d_e;
02209 d_e += 2;
02210 d_se += 2;
02211 } else {
02212 df += d_se;
02213 d_e += 2;
02214 d_se += 4;
02215 cy--;
02216 }
02217 cx++;
02218 } while (cx <= cy);
02219
02220 return (result);
02221 }
02222
02223 int filledCircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02224 {
02225
02226
02227
02228 return (filledCircleColor
02229 (dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02230 }
02231
02232
02233
02234
02235
02236
02237
02238 int ellipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
02239 {
02240 Sint16 left, right, top, bottom;
02241 int result;
02242 Sint16 x1, y1, x2, y2;
02243 int ix, iy;
02244 int h, i, j, k;
02245 int oh, oi, oj, ok;
02246 int xmh, xph, ypk, ymk;
02247 int xmi, xpi, ymj, ypj;
02248 int xmj, xpj, ymi, ypi;
02249 int xmk, xpk, ymh, yph;
02250 Uint8 *colorptr;
02251
02252
02253
02254
02255 if ((rx < 0) || (ry < 0)) {
02256 return (-1);
02257 }
02258
02259
02260
02261
02262 if (rx == 0) {
02263 return (vlineColor(dst, x, y - ry, y + ry, color));
02264 }
02265
02266
02267
02268 if (ry == 0) {
02269 return (hlineColor(dst, x - rx, x + rx, y, color));
02270 }
02271
02272
02273
02274
02275 left = dst->clip_rect.x;
02276 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02277 top = dst->clip_rect.y;
02278 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02279
02280
02281
02282
02283 x1 = x - rx;
02284 x2 = x + rx;
02285 y1 = y - ry;
02286 y2 = y + ry;
02287 if ((x1<left) && (x2<left)) {
02288 return(0);
02289 }
02290 if ((x1>right) && (x2>right)) {
02291 return(0);
02292 }
02293 if ((y1<top) && (y2<top)) {
02294 return(0);
02295 }
02296 if ((y1>bottom) && (y2>bottom)) {
02297 return(0);
02298 }
02299
02300
02301
02302
02303 oh = oi = oj = ok = 0xFFFF;
02304
02305
02306
02307
02308 result = 0;
02309
02310
02311 if (SDL_MUSTLOCK(dst)) {
02312 if (SDL_LockSurface(dst) < 0) {
02313 return (-1);
02314 }
02315 }
02316
02317
02318
02319
02320 if ((color & 255) == 255) {
02321
02322
02323
02324
02325
02326
02327
02328
02329 colorptr = (Uint8 *) & color;
02330 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02331 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
02332 } else {
02333 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
02334 }
02335
02336
02337 if (rx > ry) {
02338 ix = 0;
02339 iy = rx * 64;
02340
02341 do {
02342 h = (ix + 32) >> 6;
02343 i = (iy + 32) >> 6;
02344 j = (h * ry) / rx;
02345 k = (i * ry) / rx;
02346
02347 if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
02348 xph = x + h;
02349 xmh = x - h;
02350 if (k > 0) {
02351 ypk = y + k;
02352 ymk = y - k;
02353 result |= fastPixelColorNolock(dst, xmh, ypk, color);
02354 result |= fastPixelColorNolock(dst, xph, ypk, color);
02355 result |= fastPixelColorNolock(dst, xmh, ymk, color);
02356 result |= fastPixelColorNolock(dst, xph, ymk, color);
02357 } else {
02358 result |= fastPixelColorNolock(dst, xmh, y, color);
02359 result |= fastPixelColorNolock(dst, xph, y, color);
02360 }
02361 ok = k;
02362 xpi = x + i;
02363 xmi = x - i;
02364 if (j > 0) {
02365 ypj = y + j;
02366 ymj = y - j;
02367 result |= fastPixelColorNolock(dst, xmi, ypj, color);
02368 result |= fastPixelColorNolock(dst, xpi, ypj, color);
02369 result |= fastPixelColorNolock(dst, xmi, ymj, color);
02370 result |= fastPixelColorNolock(dst, xpi, ymj, color);
02371 } else {
02372 result |= fastPixelColorNolock(dst, xmi, y, color);
02373 result |= fastPixelColorNolock(dst, xpi, y, color);
02374 }
02375 oj = j;
02376 }
02377
02378 ix = ix + iy / rx;
02379 iy = iy - ix / rx;
02380
02381 } while (i > h);
02382 } else {
02383 ix = 0;
02384 iy = ry * 64;
02385
02386 do {
02387 h = (ix + 32) >> 6;
02388 i = (iy + 32) >> 6;
02389 j = (h * rx) / ry;
02390 k = (i * rx) / ry;
02391
02392 if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
02393 xmj = x - j;
02394 xpj = x + j;
02395 if (i > 0) {
02396 ypi = y + i;
02397 ymi = y - i;
02398 result |= fastPixelColorNolock(dst, xmj, ypi, color);
02399 result |= fastPixelColorNolock(dst, xpj, ypi, color);
02400 result |= fastPixelColorNolock(dst, xmj, ymi, color);
02401 result |= fastPixelColorNolock(dst, xpj, ymi, color);
02402 } else {
02403 result |= fastPixelColorNolock(dst, xmj, y, color);
02404 result |= fastPixelColorNolock(dst, xpj, y, color);
02405 }
02406 oi = i;
02407 xmk = x - k;
02408 xpk = x + k;
02409 if (h > 0) {
02410 yph = y + h;
02411 ymh = y - h;
02412 result |= fastPixelColorNolock(dst, xmk, yph, color);
02413 result |= fastPixelColorNolock(dst, xpk, yph, color);
02414 result |= fastPixelColorNolock(dst, xmk, ymh, color);
02415 result |= fastPixelColorNolock(dst, xpk, ymh, color);
02416 } else {
02417 result |= fastPixelColorNolock(dst, xmk, y, color);
02418 result |= fastPixelColorNolock(dst, xpk, y, color);
02419 }
02420 oh = h;
02421 }
02422
02423 ix = ix + iy / ry;
02424 iy = iy - ix / ry;
02425
02426 } while (i > h);
02427 }
02428
02429 } else {
02430
02431 if (rx > ry) {
02432 ix = 0;
02433 iy = rx * 64;
02434
02435 do {
02436 h = (ix + 32) >> 6;
02437 i = (iy + 32) >> 6;
02438 j = (h * ry) / rx;
02439 k = (i * ry) / rx;
02440
02441 if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
02442 xph = x + h;
02443 xmh = x - h;
02444 if (k > 0) {
02445 ypk = y + k;
02446 ymk = y - k;
02447 result |= pixelColorNolock (dst, xmh, ypk, color);
02448 result |= pixelColorNolock (dst, xph, ypk, color);
02449 result |= pixelColorNolock (dst, xmh, ymk, color);
02450 result |= pixelColorNolock (dst, xph, ymk, color);
02451 } else {
02452 result |= pixelColorNolock (dst, xmh, y, color);
02453 result |= pixelColorNolock (dst, xph, y, color);
02454 }
02455 ok = k;
02456 xpi = x + i;
02457 xmi = x - i;
02458 if (j > 0) {
02459 ypj = y + j;
02460 ymj = y - j;
02461 result |= pixelColorNolock (dst, xmi, ypj, color);
02462 result |= pixelColorNolock (dst, xpi, ypj, color);
02463 result |= pixelColorNolock (dst, xmi, ymj, color);
02464 result |= pixelColor(dst, xpi, ymj, color);
02465 } else {
02466 result |= pixelColorNolock (dst, xmi, y, color);
02467 result |= pixelColorNolock (dst, xpi, y, color);
02468 }
02469 oj = j;
02470 }
02471
02472 ix = ix + iy / rx;
02473 iy = iy - ix / rx;
02474
02475 } while (i > h);
02476 } else {
02477 ix = 0;
02478 iy = ry * 64;
02479
02480 do {
02481 h = (ix + 32) >> 6;
02482 i = (iy + 32) >> 6;
02483 j = (h * rx) / ry;
02484 k = (i * rx) / ry;
02485
02486 if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
02487 xmj = x - j;
02488 xpj = x + j;
02489 if (i > 0) {
02490 ypi = y + i;
02491 ymi = y - i;
02492 result |= pixelColorNolock (dst, xmj, ypi, color);
02493 result |= pixelColorNolock (dst, xpj, ypi, color);
02494 result |= pixelColorNolock (dst, xmj, ymi, color);
02495 result |= pixelColorNolock (dst, xpj, ymi, color);
02496 } else {
02497 result |= pixelColorNolock (dst, xmj, y, color);
02498 result |= pixelColorNolock (dst, xpj, y, color);
02499 }
02500 oi = i;
02501 xmk = x - k;
02502 xpk = x + k;
02503 if (h > 0) {
02504 yph = y + h;
02505 ymh = y - h;
02506 result |= pixelColorNolock (dst, xmk, yph, color);
02507 result |= pixelColorNolock (dst, xpk, yph, color);
02508 result |= pixelColorNolock (dst, xmk, ymh, color);
02509 result |= pixelColorNolock (dst, xpk, ymh, color);
02510 } else {
02511 result |= pixelColorNolock (dst, xmk, y, color);
02512 result |= pixelColorNolock (dst, xpk, y, color);
02513 }
02514 oh = h;
02515 }
02516
02517 ix = ix + iy / ry;
02518 iy = iy - ix / ry;
02519
02520 } while (i > h);
02521 }
02522
02523 }
02524
02525
02526 if (SDL_MUSTLOCK(dst)) {
02527 SDL_UnlockSurface(dst);
02528 }
02529
02530 return (result);
02531 }
02532
02533 int ellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02534 {
02535
02536
02537
02538 return (ellipseColor(dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02539 }
02540
02541
02542
02543
02544
02545 int aaellipseColor(SDL_Surface * dst, Sint16 xc, Sint16 yc, Sint16 rx, Sint16 ry, Uint32 color)
02546 {
02547 Sint16 left, right, top, bottom;
02548 Sint16 x1,y1,x2,y2;
02549 int i;
02550 int a2, b2, ds, dt, dxt, t, s, d;
02551 Sint16 x, y, xs, ys, dyt, xx, yy, xc2, yc2;
02552 float cp;
02553 Uint8 weight, iweight;
02554 int result;
02555
02556
02557
02558
02559 if ((rx < 0) || (ry < 0)) {
02560 return (-1);
02561 }
02562
02563
02564
02565
02566 if (rx == 0) {
02567 return (vlineColor(dst, xc, yc - ry, yc + ry, color));
02568 }
02569
02570
02571
02572 if (ry == 0) {
02573 return (hlineColor(dst, xc - rx, xc + rx, yc, color));
02574 }
02575
02576
02577
02578
02579 left = dst->clip_rect.x;
02580 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02581 top = dst->clip_rect.y;
02582 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02583
02584
02585
02586
02587 x1 = xc - rx;
02588 x2 = xc + rx;
02589 y1 = yc - ry;
02590 y2 = yc + ry;
02591 if ((x1<left) && (x2<left)) {
02592 return(0);
02593 }
02594 if ((x1>right) && (x2>right)) {
02595 return(0);
02596 }
02597 if ((y1<top) && (y2<top)) {
02598 return(0);
02599 }
02600 if ((y1>bottom) && (y2>bottom)) {
02601 return(0);
02602 }
02603
02604
02605 a2 = rx * rx;
02606 b2 = ry * ry;
02607
02608 ds = 2 * a2;
02609 dt = 2 * b2;
02610
02611 xc2 = 2 * xc;
02612 yc2 = 2 * yc;
02613
02614 dxt = (int) (a2 / sqrt(a2 + b2));
02615
02616 t = 0;
02617 s = -2 * a2 * ry;
02618 d = 0;
02619
02620 x = xc;
02621 y = yc - ry;
02622
02623
02624 result = 0;
02625
02626
02627 if (SDL_MUSTLOCK(dst)) {
02628 if (SDL_LockSurface(dst) < 0) {
02629 return (-1);
02630 }
02631 }
02632
02633
02634 result |= pixelColorNolock(dst, x, y, color);
02635 result |= pixelColorNolock(dst, xc2 - x, y, color);
02636 result |= pixelColorNolock(dst, x, yc2 - y, color);
02637 result |= pixelColorNolock(dst, xc2 - x, yc2 - y, color);
02638
02639 for (i = 1; i <= dxt; i++) {
02640 x--;
02641 d += t - b2;
02642
02643 if (d >= 0)
02644 ys = y - 1;
02645 else if ((d - s - a2) > 0) {
02646 if ((2 * d - s - a2) >= 0)
02647 ys = y + 1;
02648 else {
02649 ys = y;
02650 y++;
02651 d -= s + a2;
02652 s += ds;
02653 }
02654 } else {
02655 y++;
02656 ys = y + 1;
02657 d -= s + a2;
02658 s += ds;
02659 }
02660
02661 t -= dt;
02662
02663
02664 if (s != 0.0) {
02665 cp = (float) abs(d) / (float) abs(s);
02666 if (cp > 1.0) {
02667 cp = 1.0;
02668 }
02669 } else {
02670 cp = 1.0;
02671 }
02672
02673
02674 weight = (Uint8) (cp * 255);
02675 iweight = 255 - weight;
02676
02677
02678 xx = xc2 - x;
02679 result |= pixelColorWeightNolock(dst, x, y, color, iweight);
02680 result |= pixelColorWeightNolock(dst, xx, y, color, iweight);
02681
02682 result |= pixelColorWeightNolock(dst, x, ys, color, weight);
02683 result |= pixelColorWeightNolock(dst, xx, ys, color, weight);
02684
02685
02686 yy = yc2 - y;
02687 result |= pixelColorWeightNolock(dst, x, yy, color, iweight);
02688 result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
02689
02690 yy = yc2 - ys;
02691 result |= pixelColorWeightNolock(dst, x, yy, color, weight);
02692 result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
02693 }
02694
02695 dyt = abs(y - yc);
02696
02697 for (i = 1; i <= dyt; i++) {
02698 y++;
02699 d -= s + a2;
02700
02701 if (d <= 0)
02702 xs = x + 1;
02703 else if ((d + t - b2) < 0) {
02704 if ((2 * d + t - b2) <= 0)
02705 xs = x - 1;
02706 else {
02707 xs = x;
02708 x--;
02709 d += t - b2;
02710 t -= dt;
02711 }
02712 } else {
02713 x--;
02714 xs = x - 1;
02715 d += t - b2;
02716 t -= dt;
02717 }
02718
02719 s += ds;
02720
02721
02722 if (t != 0.0) {
02723 cp = (float) abs(d) / (float) abs(t);
02724 if (cp > 1.0) {
02725 cp = 1.0;
02726 }
02727 } else {
02728 cp = 1.0;
02729 }
02730
02731
02732 weight = (Uint8) (cp * 255);
02733 iweight = 255 - weight;
02734
02735
02736 xx = xc2 - x;
02737 yy = yc2 - y;
02738 result |= pixelColorWeightNolock(dst, x, y, color, iweight);
02739 result |= pixelColorWeightNolock(dst, xx, y, color, iweight);
02740
02741 result |= pixelColorWeightNolock(dst, x, yy, color, iweight);
02742 result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
02743
02744
02745 xx = 2 * xc - xs;
02746 result |= pixelColorWeightNolock(dst, xs, y, color, weight);
02747 result |= pixelColorWeightNolock(dst, xx, y, color, weight);
02748
02749 result |= pixelColorWeightNolock(dst, xs, yy, color, weight);
02750 result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
02751
02752
02753 }
02754
02755
02756 if (SDL_MUSTLOCK(dst)) {
02757 SDL_UnlockSurface(dst);
02758 }
02759
02760 return (result);
02761 }
02762
02763 int aaellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02764 {
02765
02766
02767
02768 return (aaellipseColor
02769 (dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02770 }
02771
02772
02773
02774
02775
02776
02777
02778 int filledEllipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
02779 {
02780 Sint16 left, right, top, bottom;
02781 int result;
02782 Sint16 x1, y1, x2, y2;
02783 int ix, iy;
02784 int h, i, j, k;
02785 int oh, oi, oj, ok;
02786 int xmh, xph;
02787 int xmi, xpi;
02788 int xmj, xpj;
02789 int xmk, xpk;
02790
02791
02792
02793
02794 if ((rx < 0) || (ry < 0)) {
02795 return (-1);
02796 }
02797
02798
02799
02800
02801 if (rx == 0) {
02802 return (vlineColor(dst, x, y - ry, y + ry, color));
02803 }
02804
02805
02806
02807 if (ry == 0) {
02808 return (hlineColor(dst, x - rx, x + rx, y, color));
02809 }
02810
02811
02812
02813
02814 left = dst->clip_rect.x;
02815 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02816 top = dst->clip_rect.y;
02817 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02818
02819
02820
02821
02822 x1 = x - rx;
02823 x2 = x + rx;
02824 y1 = y - ry;
02825 y2 = y + ry;
02826 if ((x1<left) && (x2<left)) {
02827 return(0);
02828 }
02829 if ((x1>right) && (x2>right)) {
02830 return(0);
02831 }
02832 if ((y1<top) && (y2<top)) {
02833 return(0);
02834 }
02835 if ((y1>bottom) && (y2>bottom)) {
02836 return(0);
02837 }
02838
02839
02840
02841
02842 oh = oi = oj = ok = 0xFFFF;
02843
02844
02845
02846
02847 result = 0;
02848 if (rx > ry) {
02849 ix = 0;
02850 iy = rx * 64;
02851
02852 do {
02853 h = (ix + 32) >> 6;
02854 i = (iy + 32) >> 6;
02855 j = (h * ry) / rx;
02856 k = (i * ry) / rx;
02857
02858 if ((ok != k) && (oj != k)) {
02859 xph = x + h;
02860 xmh = x - h;
02861 if (k > 0) {
02862 result |= hlineColor(dst, xmh, xph, y + k, color);
02863 result |= hlineColor(dst, xmh, xph, y - k, color);
02864 } else {
02865 result |= hlineColor(dst, xmh, xph, y, color);
02866 }
02867 ok = k;
02868 }
02869 if ((oj != j) && (ok != j) && (k != j)) {
02870 xmi = x - i;
02871 xpi = x + i;
02872 if (j > 0) {
02873 result |= hlineColor(dst, xmi, xpi, y + j, color);
02874 result |= hlineColor(dst, xmi, xpi, y - j, color);
02875 } else {
02876 result |= hlineColor(dst, xmi, xpi, y, color);
02877 }
02878 oj = j;
02879 }
02880
02881 ix = ix + iy / rx;
02882 iy = iy - ix / rx;
02883
02884 } while (i > h);
02885 } else {
02886 ix = 0;
02887 iy = ry * 64;
02888
02889 do {
02890 h = (ix + 32) >> 6;
02891 i = (iy + 32) >> 6;
02892 j = (h * rx) / ry;
02893 k = (i * rx) / ry;
02894
02895 if ((oi != i) && (oh != i)) {
02896 xmj = x - j;
02897 xpj = x + j;
02898 if (i > 0) {
02899 result |= hlineColor(dst, xmj, xpj, y + i, color);
02900 result |= hlineColor(dst, xmj, xpj, y - i, color);
02901 } else {
02902 result |= hlineColor(dst, xmj, xpj, y, color);
02903 }
02904 oi = i;
02905 }
02906 if ((oh != h) && (oi != h) && (i != h)) {
02907 xmk = x - k;
02908 xpk = x + k;
02909 if (h > 0) {
02910 result |= hlineColor(dst, xmk, xpk, y + h, color);
02911 result |= hlineColor(dst, xmk, xpk, y - h, color);
02912 } else {
02913 result |= hlineColor(dst, xmk, xpk, y, color);
02914 }
02915 oh = h;
02916 }
02917
02918 ix = ix + iy / ry;
02919 iy = iy - ix / ry;
02920
02921 } while (i > h);
02922 }
02923
02924 return (result);
02925 }
02926
02927
02928 int filledEllipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02929 {
02930
02931
02932
02933 return (filledEllipseColor
02934 (dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02935 }
02936
02937
02938
02939
02940
02941 int filledpieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
02942 {
02943 Sint16 left, right, top, bottom;
02944 Sint16 x1, y1, x2, y2;
02945 int result;
02946 double angle, start_angle, end_angle;
02947 double deltaAngle;
02948 double dr;
02949 int posX, posY;
02950 int numpoints, i;
02951 Sint16 *vx, *vy;
02952
02953
02954
02955
02956 if (rad < 0) {
02957 return (-1);
02958 }
02959
02960
02961
02962
02963 start = start % 360;
02964 end = end % 360;
02965
02966
02967
02968
02969 if (rad == 0) {
02970 return (pixelColor(dst, x, y, color));
02971 }
02972
02973
02974
02975
02976 left = dst->clip_rect.x;
02977 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02978 top = dst->clip_rect.y;
02979 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02980
02981
02982
02983
02984 x1 = x - rad;
02985 x2 = x + rad;
02986 y1 = y - rad;
02987 y2 = y + rad;
02988 if ((x1<left) && (x2<left)) {
02989 return(0);
02990 }
02991 if ((x1>right) && (x2>right)) {
02992 return(0);
02993 }
02994 if ((y1<top) && (y2<top)) {
02995 return(0);
02996 }
02997 if ((y1>bottom) && (y2>bottom)) {
02998 return(0);
02999 }
03000
03001
03002
03003
03004 dr = (double) rad;
03005 deltaAngle = 3.0 / dr;
03006 start_angle = (double) start *(2.0 * M_PI / 360.0);
03007 end_angle = (double) end *(2.0 * M_PI / 360.0);
03008 if (start > end) {
03009 end_angle += (2.0 * M_PI);
03010 }
03011
03012
03013 numpoints = 1;
03014 angle = start_angle;
03015 while (angle <= end_angle) {
03016 angle += deltaAngle;
03017 numpoints++;
03018 }
03019
03020
03021 if (numpoints == 1) {
03022 return (pixelColor(dst, x, y, color));
03023 } else if (numpoints == 2) {
03024 posX = x + (int) (dr * cos(start_angle));
03025 posY = y + (int) (dr * sin(start_angle));
03026 return (lineColor(dst, x, y, posX, posY, color));
03027 }
03028
03029
03030 vx = vy = (Uint16 *) malloc(2 * sizeof(Uint16) * numpoints);
03031 if (vx == NULL) {
03032 return (-1);
03033 }
03034 vy += numpoints;
03035
03036
03037 vx[0] = x;
03038 vy[0] = y;
03039
03040
03041 i = 1;
03042 angle = start_angle;
03043 while (angle <= end_angle) {
03044 vx[i] = x + (int) (dr * cos(angle));
03045 vy[i] = y + (int) (dr * sin(angle));
03046 angle += deltaAngle;
03047 i++;
03048 }
03049
03050
03051 result = filledPolygonColor(dst, vx, vy, numpoints, color);
03052
03053
03054 free(vx);
03055
03056 return (result);
03057 }
03058
03059 int filledpieRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
03060 Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03061 {
03062 return (filledpieColor(dst, x, y, rad, start, end,
03063 ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03064
03065 }
03066
03067
03068
03069
03070 int trigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
03071 {
03072 Sint16 vx[3];
03073 Sint16 vy[3];
03074
03075 vx[0]=x1;
03076 vx[1]=x2;
03077 vx[2]=x3;
03078 vy[0]=y1;
03079 vy[1]=y2;
03080 vy[2]=y3;
03081
03082 return(polygonColor(dst,vx,vy,3,color));
03083 }
03084
03085 int trigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
03086 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03087 {
03088 Sint16 vx[3];
03089 Sint16 vy[3];
03090
03091 vx[0]=x1;
03092 vx[1]=x2;
03093 vx[2]=x3;
03094 vy[0]=y1;
03095 vy[1]=y2;
03096 vy[2]=y3;
03097
03098 return(polygonRGBA(dst,vx,vy,3,r,g,b,a));
03099 }
03100
03101
03102
03103 int aatrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
03104 {
03105 Sint16 vx[3];
03106 Sint16 vy[3];
03107
03108 vx[0]=x1;
03109 vx[1]=x2;
03110 vx[2]=x3;
03111 vy[0]=y1;
03112 vy[1]=y2;
03113 vy[2]=y3;
03114
03115 return(aapolygonColor(dst,vx,vy,3,color));
03116 }
03117
03118 int aatrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
03119 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03120 {
03121 Sint16 vx[3];
03122 Sint16 vy[3];
03123
03124 vx[0]=x1;
03125 vx[1]=x2;
03126 vx[2]=x3;
03127 vy[0]=y1;
03128 vy[1]=y2;
03129 vy[2]=y3;
03130
03131 return(aapolygonRGBA(dst,vx,vy,3,r,g,b,a));
03132 }
03133
03134
03135
03136 int filledTrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, int color)
03137 {
03138 Sint16 vx[3];
03139 Sint16 vy[3];
03140
03141 vx[0]=x1;
03142 vx[1]=x2;
03143 vx[2]=x3;
03144 vy[0]=y1;
03145 vy[1]=y2;
03146 vy[2]=y3;
03147
03148 return(filledPolygonColor(dst,vx,vy,3,color));
03149 }
03150
03151 int filledTrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
03152 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03153 {
03154 Sint16 vx[3];
03155 Sint16 vy[3];
03156
03157 vx[0]=x1;
03158 vx[1]=x2;
03159 vx[2]=x3;
03160 vy[0]=y1;
03161 vy[1]=y2;
03162 vy[2]=y3;
03163
03164 return(filledPolygonRGBA(dst,vx,vy,3,r,g,b,a));
03165 }
03166
03167
03168
03169 int polygonColor(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, Uint32 color)
03170 {
03171 int result;
03172 int i;
03173 Sint16 *x1, *y1, *x2, *y2;
03174
03175
03176
03177
03178 if (n < 3) {
03179 return (-1);
03180 }
03181
03182
03183
03184
03185 x1 = x2 = vx;
03186 y1 = y2 = vy;
03187 x2++;
03188 y2++;
03189
03190
03191
03192
03193 result = 0;
03194 for (i = 1; i < n; i++) {
03195 result |= lineColor(dst, *x1, *y1, *x2, *y2, color);
03196 x1 = x2;
03197 y1 = y2;
03198 x2++;
03199 y2++;
03200 }
03201 result |= lineColor(dst, *x1, *y1, *vx, *vy, color);
03202
03203 return (result);
03204 }
03205
03206 int polygonRGBA(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03207 {
03208
03209
03210
03211 return (polygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03212 }
03213
03214
03215
03216 int aapolygonColor(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, Uint32 color)
03217 {
03218 int result;
03219 int i;
03220 Sint16 *x1, *y1, *x2, *y2;
03221
03222
03223
03224
03225 if (n < 3) {
03226 return (-1);
03227 }
03228
03229
03230
03231
03232 x1 = x2 = vx;
03233 y1 = y2 = vy;
03234 x2++;
03235 y2++;
03236
03237
03238
03239
03240 result = 0;
03241 for (i = 1; i < n; i++) {
03242 result |= aalineColorInt(dst, *x1, *y1, *x2, *y2, color, 0);
03243 x1 = x2;
03244 y1 = y2;
03245 x2++;
03246 y2++;
03247 }
03248 result |= aalineColorInt(dst, *x1, *y1, *vx, *vy, color, 0);
03249
03250 return (result);
03251 }
03252
03253 int aapolygonRGBA(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03254 {
03255
03256
03257
03258 return (aapolygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03259 }
03260
03261
03262
03263 int gfxPrimitivesCompareInt(const void *a, const void *b);
03264
03265 static int *gfxPrimitivesPolyInts = NULL;
03266 static int gfxPrimitivesPolyAllocated = 0;
03267
03268 int filledPolygonColor(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, int color)
03269 {
03270 int result;
03271 int i;
03272 int x, y, xa, xb;
03273 int miny, maxy;
03274 int x1, y1;
03275 int x2, y2;
03276 int ind1, ind2;
03277 int ints;
03278
03279
03280
03281
03282 if (n < 3) {
03283 return -1;
03284 }
03285
03286
03287
03288
03289 if (!gfxPrimitivesPolyAllocated) {
03290 gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
03291 gfxPrimitivesPolyAllocated = n;
03292 } else {
03293 if (gfxPrimitivesPolyAllocated < n) {
03294 gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
03295 gfxPrimitivesPolyAllocated = n;
03296 }
03297 }
03298
03299
03300
03301
03302 miny = vy[0];
03303 maxy = vy[0];
03304 for (i = 1; (i < n); i++) {
03305 if (vy[i] < miny) {
03306 miny = vy[i];
03307 } else if (vy[i] > maxy) {
03308 maxy = vy[i];
03309 }
03310 }
03311
03312
03313
03314
03315 result = 0;
03316 for (y = miny; (y <= maxy); y++) {
03317 ints = 0;
03318 for (i = 0; (i < n); i++) {
03319 if (!i) {
03320 ind1 = n - 1;
03321 ind2 = 0;
03322 } else {
03323 ind1 = i - 1;
03324 ind2 = i;
03325 }
03326 y1 = vy[ind1];
03327 y2 = vy[ind2];
03328 if (y1 < y2) {
03329 x1 = vx[ind1];
03330 x2 = vx[ind2];
03331 } else if (y1 > y2) {
03332 y2 = vy[ind1];
03333 y1 = vy[ind2];
03334 x2 = vx[ind1];
03335 x1 = vx[ind2];
03336 } else {
03337 continue;
03338 }
03339 if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
03340 gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
03341 }
03342
03343 }
03344
03345 qsort(gfxPrimitivesPolyInts, ints, sizeof(int), gfxPrimitivesCompareInt);
03346
03347 for (i = 0; (i < ints); i += 2) {
03348 xa = gfxPrimitivesPolyInts[i] + 1;
03349 xa = (xa >> 16) + ((xa & 32768) >> 15);
03350 xb = gfxPrimitivesPolyInts[i+1] - 1;
03351 xb = (xb >> 16) + ((xb & 32768) >> 15);
03352 result |= hlineColor(dst, xa, xb, y, color);
03353 }
03354 }
03355
03356 return (result);
03357 }
03358
03359 int filledPolygonRGBA(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03360 {
03361
03362
03363
03364 return (filledPolygonColor
03365 (dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03366 }
03367
03368 int gfxPrimitivesCompareInt(const void *a, const void *b)
03369 {
03370 return (*(const int *) a) - (*(const int *) b);
03371 }
03372
03373
03374
03375
03376
03377
03378
03379 double evaluateBezier (double *data, int ndata, double t)
03380 {
03381 double mu, result;
03382 int n,k,kn,nn,nkn;
03383 double blend,muk,munk;
03384
03385
03386 if (t<0.0) {
03387 return(data[0]);
03388 }
03389 if (t>=(double)ndata) {
03390 return(data[ndata-1]);
03391 }
03392
03393
03394 mu=t/(double)ndata;
03395
03396
03397 n=ndata-1;
03398 result=0.0;
03399 muk = 1;
03400 munk = pow(1-mu,(double)n);
03401 for (k=0;k<=n;k++) {
03402 nn = n;
03403 kn = k;
03404 nkn = n - k;
03405 blend = muk * munk;
03406 muk *= mu;
03407 munk /= (1-mu);
03408 while (nn >= 1) {
03409 blend *= nn;
03410 nn--;
03411 if (kn > 1) {
03412 blend /= (double)kn;
03413 kn--;
03414 }
03415 if (nkn > 1) {
03416 blend /= (double)nkn;
03417 nkn--;
03418 }
03419 }
03420 result += data[k] * blend;
03421 }
03422
03423 return(result);
03424 }
03425
03426 int bezierColor(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, int s, Uint32 color)
03427 {
03428 int result;
03429 int i;
03430 double *x, *y, t, stepsize;
03431 Sint16 x1, y1, x2, y2;
03432
03433
03434
03435
03436 if (n < 3) {
03437 return (-1);
03438 }
03439 if (s < 2) {
03440 return (-1);
03441 }
03442
03443
03444
03445
03446 stepsize=(double)1.0/(double)s;
03447
03448
03449 if ((x=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
03450 return(-1);
03451 }
03452 if ((y=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
03453 free(x);
03454 return(-1);
03455 }
03456 for (i=0; i<n; i++) {
03457 x[i]=vx[i];
03458 y[i]=vy[i];
03459 }
03460 x[n]=vx[0];
03461 y[n]=vy[0];
03462
03463
03464
03465
03466 result = 0;
03467 t=0.0;
03468 x1=evaluateBezier(x,n+1,t);
03469 y1=evaluateBezier(y,n+1,t);
03470 for (i = 0; i <= (n*s); i++) {
03471 t += stepsize;
03472 x2=(Sint16)evaluateBezier(x,n,t);
03473 y2=(Sint16)evaluateBezier(y,n,t);
03474 result |= lineColor(dst, x1, y1, x2, y2, color);
03475 x1 = x2;
03476 y1 = y2;
03477 }
03478
03479
03480 free(x);
03481 free(y);
03482
03483 return (result);
03484 }
03485
03486 int bezierRGBA(SDL_Surface * dst, Sint16 * vx, Sint16 * vy, int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03487 {
03488
03489
03490
03491 return (bezierColor(dst, vx, vy, n, s, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03492 }