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 #include "SDL_rotozoom.h"
00016 #include "SDL_gfxPrimitives_font.h"
00017
00018
00019
00020 #define DEFAULT_ALPHA_PIXEL_ROUTINE
00021 #undef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
00022
00023
00024
00028 typedef struct {
00029 Sint16 x, y;
00030 int dx, dy, s1, s2, swapdir, error;
00031 Uint32 count;
00032 } SDL_gfxBresenhamIterator;
00033
00037 typedef struct {
00038 Uint32 color;
00039 SDL_Surface *dst;
00040 int u, v;
00041 int ku, kt, kv, kd;
00042 int oct2;
00043 int quad4;
00044 Sint16 last1x, last1y, last2x, last2y, first1x, first1y, first2x, first2y, tempx, tempy;
00045 } SDL_gfxMurphyIterator;
00046
00047
00048
00049 #define clip_xmin(surface) surface->clip_rect.x
00050 #define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
00051 #define clip_ymin(surface) surface->clip_rect.y
00052 #define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
00053
00064 int fastPixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00065 {
00066 int bpp;
00067 Uint8 *p;
00068
00069
00070
00071
00072 if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst)) && (y <= clip_ymax(dst))) {
00073
00074
00075
00076
00077 bpp = dst->format->BytesPerPixel;
00078 p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00079 switch (bpp) {
00080 case 1:
00081 *p = color;
00082 break;
00083 case 2:
00084 *(Uint16 *) p = color;
00085 break;
00086 case 3:
00087 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00088 p[0] = (color >> 16) & 0xff;
00089 p[1] = (color >> 8) & 0xff;
00090 p[2] = color & 0xff;
00091 } else {
00092 p[0] = color & 0xff;
00093 p[1] = (color >> 8) & 0xff;
00094 p[2] = (color >> 16) & 0xff;
00095 }
00096 break;
00097 case 4:
00098 *(Uint32 *) p = color;
00099 break;
00100 }
00101
00102
00103 }
00104
00105 return (0);
00106 }
00107
00121 int fastPixelColorNolockNoclip(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00122 {
00123 int bpp;
00124 Uint8 *p;
00125
00126
00127
00128
00129 bpp = dst->format->BytesPerPixel;
00130 p = (Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00131 switch (bpp) {
00132 case 1:
00133 *p = color;
00134 break;
00135 case 2:
00136 *(Uint16 *) p = color;
00137 break;
00138 case 3:
00139 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00140 p[0] = (color >> 16) & 0xff;
00141 p[1] = (color >> 8) & 0xff;
00142 p[2] = color & 0xff;
00143 } else {
00144 p[0] = color & 0xff;
00145 p[1] = (color >> 8) & 0xff;
00146 p[2] = (color >> 16) & 0xff;
00147 }
00148 break;
00149 case 4:
00150 *(Uint32 *) p = color;
00151 break;
00152 }
00153
00154 return (0);
00155 }
00156
00167 int fastPixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00168 {
00169 int result;
00170
00171
00172
00173
00174 if (SDL_MUSTLOCK(dst)) {
00175 if (SDL_LockSurface(dst) < 0) {
00176 return (-1);
00177 }
00178 }
00179
00180 result = fastPixelColorNolock(dst, x, y, color);
00181
00182
00183
00184
00185 if (SDL_MUSTLOCK(dst)) {
00186 SDL_UnlockSurface(dst);
00187 }
00188
00189 return (result);
00190 }
00191
00205 int fastPixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00206 {
00207 Uint32 color;
00208
00209
00210
00211
00212 color = SDL_MapRGBA(dst->format, r, g, b, a);
00213
00214
00215
00216
00217 return (fastPixelColor(dst, x, y, color));
00218 }
00219
00233 int fastPixelRGBANolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00234 {
00235 Uint32 color;
00236
00237
00238
00239
00240 color = SDL_MapRGBA(dst->format, r, g, b, a);
00241
00242
00243
00244
00245 return (fastPixelColorNolock(dst, x, y, color));
00246 }
00247
00263 int _putPixelAlpha(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha)
00264 {
00265 SDL_PixelFormat *format;
00266 Uint32 Rmask, Gmask, Bmask, Amask;
00267 Uint32 Rshift, Gshift, Bshift, Ashift;
00268 Uint32 R, G, B, A;
00269
00270 if (dst == NULL)
00271 {
00272 return (-1);
00273 }
00274
00275 if (x >= clip_xmin(dst) && x <= clip_xmax(dst) &&
00276 y >= clip_ymin(dst) && y <= clip_ymax(dst))
00277 {
00278
00279 format = dst->format;
00280
00281 switch (format->BytesPerPixel) {
00282 case 1:
00283 {
00284 if (alpha == 255) {
00285 *((Uint8 *) dst->pixels + y * dst->pitch + x) = color;
00286 } else {
00287 Uint8 *pixel = (Uint8 *) dst->pixels + y * dst->pitch + x;
00288 SDL_Palette *palette = format->palette;
00289 SDL_Color *colors = palette->colors;
00290 SDL_Color dColor = colors[*pixel];
00291 SDL_Color sColor = colors[color];
00292 Uint8 dR = dColor.r;
00293 Uint8 dG = dColor.g;
00294 Uint8 dB = dColor.b;
00295 Uint8 sR = sColor.r;
00296 Uint8 sG = sColor.g;
00297 Uint8 sB = sColor.b;
00298
00299 dR = dR + ((sR - dR) * alpha >> 8);
00300 dG = dG + ((sG - dG) * alpha >> 8);
00301 dB = dB + ((sB - dB) * alpha >> 8);
00302
00303 *pixel = SDL_MapRGB(format, dR, dG, dB);
00304 }
00305 }
00306 break;
00307
00308 case 2:
00309 {
00310 if (alpha == 255) {
00311 *((Uint16 *) dst->pixels + y * dst->pitch / 2 + x) = color;
00312 } else {
00313 Uint16 *pixel = (Uint16 *) dst->pixels + y * dst->pitch / 2 + x;
00314 Uint32 dc = *pixel;
00315
00316 Rmask = format->Rmask;
00317 Gmask = format->Gmask;
00318 Bmask = format->Bmask;
00319 Amask = format->Amask;
00320 R = ((dc & Rmask) + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00321 G = ((dc & Gmask) + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00322 B = ((dc & Bmask) + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00323 if (Amask) {
00324 A = ((dc & Amask) + (((color & Amask) - (dc & Amask)) * alpha >> 8)) & Amask;
00325 }
00326 *pixel = R | G | B | A;
00327 }
00328 }
00329 break;
00330
00331 case 3:
00332 {
00333 Uint8 Rshift8, Gshift8, Bshift8, Ashift8;
00334 Uint8 *pixel = (Uint8 *) dst->pixels + y * dst->pitch + x * 3;
00335
00336 Rshift = format->Rshift;
00337 Gshift = format->Gshift;
00338 Bshift = format->Bshift;
00339 Ashift = format->Ashift;
00340
00341 Rshift8 = Rshift / 8;
00342 Gshift8 = Gshift / 8;
00343 Bshift8 = Bshift / 8;
00344 Ashift8 = Ashift / 8;
00345
00346 if (alpha == 255) {
00347 *(pixel + Rshift8) = color >> Rshift;
00348 *(pixel + Gshift8) = color >> Gshift;
00349 *(pixel + Bshift8) = color >> Bshift;
00350 *(pixel + Ashift8) = color >> Ashift;
00351 } else {
00352 Uint8 dR, dG, dB, dA = 0;
00353 Uint8 sR, sG, sB, sA = 0;
00354
00355 dR = *((pixel) + Rshift8);
00356 dG = *((pixel) + Gshift8);
00357 dB = *((pixel) + Bshift8);
00358 dA = *((pixel) + Ashift8);
00359
00360 sR = (color >> Rshift) & 0xff;
00361 sG = (color >> Gshift) & 0xff;
00362 sB = (color >> Bshift) & 0xff;
00363 sA = (color >> Ashift) & 0xff;
00364
00365 dR = dR + ((sR - dR) * alpha >> 8);
00366 dG = dG + ((sG - dG) * alpha >> 8);
00367 dB = dB + ((sB - dB) * alpha >> 8);
00368 dA = dA + ((sA - dA) * alpha >> 8);
00369
00370 *((pixel) + Rshift8) = dR;
00371 *((pixel) + Gshift8) = dG;
00372 *((pixel) + Bshift8) = dB;
00373 *((pixel) + Ashift8) = dA;
00374 }
00375 }
00376 break;
00377
00378 #ifdef DEFAULT_ALPHA_PIXEL_ROUTINE
00379
00380 case 4:
00381 {
00382 if (alpha == 255) {
00383 *((Uint32 *) dst->pixels + y * dst->pitch / 4 + x) = color;
00384 } else {
00385 Uint32 *pixel = (Uint32 *) dst->pixels + y * dst->pitch / 4 + x;
00386 Uint32 dc = *pixel;
00387
00388 Rmask = format->Rmask;
00389 Gmask = format->Gmask;
00390 Bmask = format->Bmask;
00391 Amask = format->Amask;
00392
00393 Rshift = format->Rshift;
00394 Gshift = format->Gshift;
00395 Bshift = format->Bshift;
00396 Ashift = format->Ashift;
00397
00398 A = 0;
00399 R = ((dc & Rmask) + (((((color & Rmask) - (dc & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
00400 G = ((dc & Gmask) + (((((color & Gmask) - (dc & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
00401 B = ((dc & Bmask) + (((((color & Bmask) - (dc & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
00402 if (Amask) {
00403 A = ((dc & Amask) + (((((color & Amask) - (dc & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
00404 }
00405 *pixel = R | G | B | A;
00406 }
00407 }
00408 break;
00409 #endif
00410
00411 #ifdef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
00412
00413 case 4:{
00414 if (alpha == 255) {
00415 *((Uint32 *) dst->pixels + y * dst->pitch / 4 + x) = color;
00416 } else {
00417 Uint32 *pixel = (Uint32 *) dst->pixels + y * dst->pitch / 4 + x;
00418 Uint32 dR, dG, dB, dA;
00419 Uint32 dc = *pixel;
00420
00421 Uint32 surfaceAlpha, preMultR, preMultG, preMultB;
00422 Uint32 aTmp;
00423
00424 Rmask = format->Rmask;
00425 Gmask = format->Gmask;
00426 Bmask = format->Bmask;
00427 Amask = format->Amask;
00428
00429 dR = (color & Rmask);
00430 dG = (color & Gmask);
00431 dB = (color & Bmask);
00432 dA = (color & Amask);
00433
00434 Rshift = format->Rshift;
00435 Gshift = format->Gshift;
00436 Bshift = format->Bshift;
00437 Ashift = format->Ashift;
00438
00439 preMultR = (alpha * (dR >> Rshift));
00440 preMultG = (alpha * (dG >> Gshift));
00441 preMultB = (alpha * (dB >> Bshift));
00442
00443 surfaceAlpha = ((dc & Amask) >> Ashift);
00444 aTmp = (255 - alpha);
00445 if (A = 255 - ((aTmp * (255 - surfaceAlpha)) >> 8 )) {
00446 aTmp *= surfaceAlpha;
00447 R = (preMultR + ((aTmp * ((dc & Rmask) >> Rshift)) >> 8)) / A << Rshift & Rmask;
00448 G = (preMultG + ((aTmp * ((dc & Gmask) >> Gshift)) >> 8)) / A << Gshift & Gmask;
00449 B = (preMultB + ((aTmp * ((dc & Bmask) >> Bshift)) >> 8)) / A << Bshift & Bmask;
00450 }
00451 *pixel = R | G | B | (A << Ashift & Amask);
00452
00453 }
00454 }
00455 break;
00456 #endif
00457 }
00458 }
00459
00460 return (0);
00461 }
00462
00473 int pixelColor(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00474 {
00475 Uint8 alpha;
00476 Uint32 mcolor;
00477 int result = 0;
00478
00479
00480
00481
00482 if (SDL_MUSTLOCK(dst)) {
00483 if (SDL_LockSurface(dst) < 0) {
00484 return (-1);
00485 }
00486 }
00487
00488
00489
00490
00491 alpha = color & 0x000000ff;
00492 mcolor =
00493 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00494 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00495
00496
00497
00498
00499 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
00500
00501
00502
00503
00504 if (SDL_MUSTLOCK(dst)) {
00505 SDL_UnlockSurface(dst);
00506 }
00507
00508 return (result);
00509 }
00510
00521 int pixelColorNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color)
00522 {
00523 Uint8 alpha;
00524 Uint32 mcolor;
00525 int result = 0;
00526
00527
00528
00529
00530 alpha = color & 0x000000ff;
00531 mcolor =
00532 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00533 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00534
00535
00536
00537
00538 result = _putPixelAlpha(dst, x, y, mcolor, alpha);
00539
00540 return (result);
00541 }
00542
00543
00559 int _filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, Uint8 alpha)
00560 {
00561 SDL_PixelFormat *format;
00562 Uint32 Rmask, Bmask, Gmask, Amask;
00563 Uint32 Rshift, Bshift, Gshift, Ashift;
00564 Uint8 sR, sG, sB, sA;
00565 Uint32 R, G, B, A;
00566 Sint16 x, y;
00567
00568 format = dst->format;
00569 switch (format->BytesPerPixel) {
00570 case 1:
00571 {
00572 Uint8 *row, *pixel;
00573 Uint8 dR, dG, dB;
00574 SDL_Palette *palette = format->palette;
00575 SDL_Color *colors = palette->colors;
00576 sR = colors[color].r;
00577 sG = colors[color].g;
00578 sB = colors[color].b;
00579
00580 for (y = y1; y <= y2; y++) {
00581 row = (Uint8 *) dst->pixels + y * dst->pitch;
00582 for (x = x1; x <= x2; x++) {
00583 pixel = row + x;
00584
00585 dR = colors[*pixel].r;
00586 dG = colors[*pixel].g;
00587 dB = colors[*pixel].b;
00588
00589 dR = dR + ((sR - dR) * alpha >> 8);
00590 dG = dG + ((sG - dG) * alpha >> 8);
00591 dB = dB + ((sB - dB) * alpha >> 8);
00592
00593 *pixel = SDL_MapRGB(format, dR, dG, dB);
00594 }
00595 }
00596 }
00597 break;
00598
00599 case 2:
00600 {
00601 Uint16 *row, *pixel;
00602 Uint32 dR, dG, dB, dA;
00603 Rmask = format->Rmask;
00604 Gmask = format->Gmask;
00605 Bmask = format->Bmask;
00606 Amask = format->Amask;
00607
00608 dR = (color & Rmask);
00609 dG = (color & Gmask);
00610 dB = (color & Bmask);
00611 dA = (color & Amask);
00612
00613 A = 0;
00614
00615 for (y = y1; y <= y2; y++) {
00616 row = (Uint16 *) dst->pixels + y * dst->pitch / 2;
00617 for (x = x1; x <= x2; x++) {
00618 pixel = row + x;
00619
00620 R = ((*pixel & Rmask) + ((dR - (*pixel & Rmask)) * alpha >> 8)) & Rmask;
00621 G = ((*pixel & Gmask) + ((dG - (*pixel & Gmask)) * alpha >> 8)) & Gmask;
00622 B = ((*pixel & Bmask) + ((dB - (*pixel & Bmask)) * alpha >> 8)) & Bmask;
00623 if (Amask)
00624 {
00625 A = ((*pixel & Amask) + ((dA - (*pixel & Amask)) * alpha >> 8)) & Amask;
00626 *pixel = R | G | B | A;
00627 } else {
00628 *pixel = R | G | B;
00629 }
00630 }
00631 }
00632 }
00633 break;
00634
00635 case 3:
00636 {
00637 Uint8 *row, *pix;
00638 Uint8 dR, dG, dB, dA;
00639 Uint8 Rshift8, Gshift8, Bshift8, Ashift8;
00640
00641 Rshift = format->Rshift;
00642 Gshift = format->Gshift;
00643 Bshift = format->Bshift;
00644 Ashift = format->Ashift;
00645
00646 Rshift8 = Rshift / 8;
00647 Gshift8 = Gshift / 8;
00648 Bshift8 = Bshift / 8;
00649 Ashift8 = Ashift / 8;
00650
00651 sR = (color >> Rshift) & 0xff;
00652 sG = (color >> Gshift) & 0xff;
00653 sB = (color >> Bshift) & 0xff;
00654 sA = (color >> Ashift) & 0xff;
00655
00656 for (y = y1; y <= y2; y++) {
00657 row = (Uint8 *) dst->pixels + y * dst->pitch;
00658 for (x = x1; x <= x2; x++) {
00659 pix = row + x * 3;
00660
00661 dR = *((pix) + Rshift8);
00662 dG = *((pix) + Gshift8);
00663 dB = *((pix) + Bshift8);
00664 dA = *((pix) + Ashift8);
00665
00666 dR = dR + ((sR - dR) * alpha >> 8);
00667 dG = dG + ((sG - dG) * alpha >> 8);
00668 dB = dB + ((sB - dB) * alpha >> 8);
00669 dA = dA + ((sA - dA) * alpha >> 8);
00670
00671 *((pix) + Rshift8) = dR;
00672 *((pix) + Gshift8) = dG;
00673 *((pix) + Bshift8) = dB;
00674 *((pix) + Ashift8) = dA;
00675 }
00676 }
00677 }
00678 break;
00679
00680 #ifdef DEFAULT_ALPHA_PIXEL_ROUTINE
00681 case 4:
00682 {
00683 Uint32 *row, *pixel;
00684 Uint32 dR, dG, dB, dA;
00685
00686 Rmask = format->Rmask;
00687 Gmask = format->Gmask;
00688 Bmask = format->Bmask;
00689 Amask = format->Amask;
00690
00691 Rshift = format->Rshift;
00692 Gshift = format->Gshift;
00693 Bshift = format->Bshift;
00694 Ashift = format->Ashift;
00695
00696 dR = (color & Rmask);
00697 dG = (color & Gmask);
00698 dB = (color & Bmask);
00699 dA = (color & Amask);
00700
00701 for (y = y1; y <= y2; y++) {
00702 row = (Uint32 *) dst->pixels + y * dst->pitch / 4;
00703 for (x = x1; x <= x2; x++) {
00704 pixel = row + x;
00705
00706 R = ((*pixel & Rmask) + ((((dR - (*pixel & Rmask)) >> Rshift) * alpha >> 8) << Rshift)) & Rmask;
00707 G = ((*pixel & Gmask) + ((((dG - (*pixel & Gmask)) >> Gshift) * alpha >> 8) << Gshift)) & Gmask;
00708 B = ((*pixel & Bmask) + ((((dB - (*pixel & Bmask)) >> Bshift) * alpha >> 8) << Bshift)) & Bmask;
00709 if (Amask)
00710 {
00711 A = ((*pixel & Amask) + ((((dA - (*pixel & Amask)) >> Ashift) * alpha >> 8) << Ashift)) & Amask;
00712 *pixel = R | G | B | A;
00713 } else {
00714 *pixel = R | G | B;
00715 }
00716 }
00717 }
00718 }
00719 break;
00720 #endif
00721
00722 #ifdef EXPERIMENTAL_ALPHA_PIXEL_ROUTINE
00723 case 4:{
00724 Uint32 *row, *pixel;
00725 Uint32 dR, dG, dB, dA;
00726 Uint32 dc;
00727 Uint32 surfaceAlpha, preMultR, preMultG, preMultB;
00728 Uint32 aTmp;
00729
00730 Rmask = format->Rmask;
00731 Gmask = format->Gmask;
00732 Bmask = format->Bmask;
00733 Amask = format->Amask;
00734
00735 dR = (color & Rmask);
00736 dG = (color & Gmask);
00737 dB = (color & Bmask);
00738 dA = (color & Amask);
00739
00740 Rshift = format->Rshift;
00741 Gshift = format->Gshift;
00742 Bshift = format->Bshift;
00743 Ashift = format->Ashift;
00744
00745 preMultR = (alpha * (dR >> Rshift));
00746 preMultG = (alpha * (dG >> Gshift));
00747 preMultB = (alpha * (dB >> Bshift));
00748
00749 for (y = y1; y <= y2; y++) {
00750 row = (Uint32 *) dst->pixels + y * dst->pitch / 4;
00751 for (x = x1; x <= x2; x++) {
00752 pixel = row + x;
00753 dc = *pixel;
00754
00755 surfaceAlpha = ((dc & Amask) >> Ashift);
00756 aTmp = (255 - alpha);
00757 if (A = 255 - ((aTmp * (255 - surfaceAlpha)) >> 8 )) {
00758 aTmp *= surfaceAlpha;
00759 R = (preMultR + ((aTmp * ((dc & Rmask) >> Rshift)) >> 8)) / A << Rshift & Rmask;
00760 G = (preMultG + ((aTmp * ((dc & Gmask) >> Gshift)) >> 8)) / A << Gshift & Gmask;
00761 B = (preMultB + ((aTmp * ((dc & Bmask) >> Bshift)) >> 8)) / A << Bshift & Bmask;
00762 }
00763 *pixel = R | G | B | (A << Ashift & Amask);
00764
00765 }
00766 }
00767 }
00768 break;
00769 #endif
00770
00771 }
00772
00773 return (0);
00774 }
00775
00788 int filledRectAlpha(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
00789 {
00790 Uint8 alpha;
00791 Uint32 mcolor;
00792 int result = 0;
00793
00794
00795
00796
00797 if (SDL_MUSTLOCK(dst)) {
00798 if (SDL_LockSurface(dst) < 0) {
00799 return (-1);
00800 }
00801 }
00802
00803
00804
00805
00806 alpha = color & 0x000000ff;
00807 mcolor =
00808 SDL_MapRGBA(dst->format, (color & 0xff000000) >> 24,
00809 (color & 0x00ff0000) >> 16, (color & 0x0000ff00) >> 8, alpha);
00810
00811
00812
00813
00814 result = _filledRectAlpha(dst, x1, y1, x2, y2, mcolor, alpha);
00815
00816
00817
00818
00819 if (SDL_MUSTLOCK(dst)) {
00820 SDL_UnlockSurface(dst);
00821 }
00822
00823 return (result);
00824 }
00825
00837 int _HLineAlpha(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
00838 {
00839 return (filledRectAlpha(dst, x1, y, x2, y, color));
00840 }
00841
00853 int _VLineAlpha(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
00854 {
00855 return (filledRectAlpha(dst, x, y1, x, y2, color));
00856 }
00857
00869 int pixelColorWeight(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
00870 {
00871 Uint32 a;
00872
00873
00874
00875
00876 a = (color & (Uint32) 0x000000ff);
00877
00878
00879
00880
00881 a = ((a * weight) >> 8);
00882
00883 return (pixelColor(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
00884 }
00885
00897 int pixelColorWeightNolock(SDL_Surface * dst, Sint16 x, Sint16 y, Uint32 color, Uint32 weight)
00898 {
00899 Uint32 a;
00900
00901
00902
00903
00904 a = (color & (Uint32) 0x000000ff);
00905
00906
00907
00908
00909 a = ((a * weight) >> 8);
00910
00911 return (pixelColorNolock(dst, x, y, (color & (Uint32) 0xffffff00) | (Uint32) a));
00912 }
00913
00927 int pixelRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
00928 {
00929 Uint32 color;
00930
00931
00932
00933
00934 if (a == 255) {
00935
00936
00937
00938
00939
00940
00941 color = SDL_MapRGBA(dst->format, r, g, b, a);
00942
00943
00944
00945 return (fastPixelColor(dst, x, y, color));
00946 } else {
00947
00948
00949
00950
00951
00952
00953 return (pixelColor(dst, x, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
00954 }
00955 }
00956
00957
00973 int hlineColorStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
00974 {
00975 Sint16 left, right, top, bottom;
00976 Uint8 *pixel, *pixellast;
00977 int dx;
00978 int pixx, pixy;
00979 Sint16 w;
00980 Sint16 xtmp;
00981 int result = -1;
00982
00983
00984
00985
00986 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
00987 return(0);
00988 }
00989
00990
00991
00992
00993 if (x1 > x2) {
00994 xtmp = x1;
00995 x1 = x2;
00996 x2 = xtmp;
00997 }
00998
00999
01000
01001
01002
01003 left = dst->clip_rect.x;
01004 if (x2<left) {
01005 return(0);
01006 }
01007 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01008 if (x1>right) {
01009 return(0);
01010 }
01011 top = dst->clip_rect.y;
01012 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01013 if ((y<top) || (y>bottom)) {
01014 return (0);
01015 }
01016
01017
01018
01019
01020 if (x1 < left) {
01021 x1 = left;
01022 }
01023 if (x2 > right) {
01024 x2 = right;
01025 }
01026
01027
01028
01029
01030 w = x2 - x1;
01031
01032
01033
01034
01035 if (SDL_MUSTLOCK(dst)) {
01036 if (SDL_LockSurface(dst) < 0) {
01037 return (-1);
01038 }
01039 }
01040
01041
01042
01043
01044 dx = w;
01045 pixx = dst->format->BytesPerPixel;
01046 pixy = dst->pitch;
01047 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
01048
01049
01050
01051
01052 switch (dst->format->BytesPerPixel) {
01053 case 1:
01054 memset(pixel, color, dx+1);
01055 break;
01056 case 2:
01057 pixellast = pixel + dx + dx;
01058 for (; pixel <= pixellast; pixel += pixx) {
01059 *(Uint16 *) pixel = color;
01060 }
01061 break;
01062 case 3:
01063 pixellast = pixel + dx + dx + dx;
01064 for (; pixel <= pixellast; pixel += pixx) {
01065 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01066 pixel[0] = (color >> 16) & 0xff;
01067 pixel[1] = (color >> 8) & 0xff;
01068 pixel[2] = color & 0xff;
01069 } else {
01070 pixel[0] = color & 0xff;
01071 pixel[1] = (color >> 8) & 0xff;
01072 pixel[2] = (color >> 16) & 0xff;
01073 }
01074 }
01075 break;
01076 default:
01077 dx = dx + dx;
01078 pixellast = pixel + dx + dx;
01079 for (; pixel <= pixellast; pixel += pixx) {
01080 *(Uint32 *) pixel = color;
01081 }
01082 break;
01083 }
01084
01085
01086
01087
01088 if (SDL_MUSTLOCK(dst)) {
01089 SDL_UnlockSurface(dst);
01090 }
01091
01092
01093
01094
01095 result = 0;
01096
01097 return (result);
01098 }
01099
01117 int hlineRGBAStore(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01118 {
01119
01120
01121
01122 return (hlineColorStore(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01123 }
01124
01136 int hlineColor(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color)
01137 {
01138 Sint16 left, right, top, bottom;
01139 Uint8 *pixel, *pixellast;
01140 int dx;
01141 int pixx, pixy;
01142 Sint16 xtmp;
01143 int result = -1;
01144 Uint8 *colorptr;
01145 Uint8 color3[3];
01146
01147
01148
01149
01150 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01151 return(0);
01152 }
01153
01154
01155
01156
01157 if (x1 > x2) {
01158 xtmp = x1;
01159 x1 = x2;
01160 x2 = xtmp;
01161 }
01162
01163
01164
01165
01166
01167 left = dst->clip_rect.x;
01168 if (x2<left) {
01169 return(0);
01170 }
01171 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01172 if (x1>right) {
01173 return(0);
01174 }
01175 top = dst->clip_rect.y;
01176 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01177 if ((y<top) || (y>bottom)) {
01178 return (0);
01179 }
01180
01181
01182
01183
01184 if (x1 < left) {
01185 x1 = left;
01186 }
01187 if (x2 > right) {
01188 x2 = right;
01189 }
01190
01191
01192
01193
01194 dx = x2 - x1;
01195
01196
01197
01198
01199 if ((color & 255) == 255) {
01200
01201
01202
01203
01204
01205
01206
01207
01208 colorptr = (Uint8 *) & color;
01209 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01210 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01211 } else {
01212 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01213 }
01214
01215
01216
01217
01218 if (SDL_MUSTLOCK(dst)) {
01219 if (SDL_LockSurface(dst) < 0) {
01220 return (-1);
01221 }
01222 }
01223
01224
01225
01226
01227 pixx = dst->format->BytesPerPixel;
01228 pixy = dst->pitch;
01229 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
01230
01231
01232
01233
01234 switch (dst->format->BytesPerPixel) {
01235 case 1:
01236 memset(pixel, color, dx + 1);
01237 break;
01238 case 2:
01239 pixellast = pixel + dx + dx;
01240 for (; pixel <= pixellast; pixel += pixx) {
01241 *(Uint16 *) pixel = color;
01242 }
01243 break;
01244 case 3:
01245 pixellast = pixel + dx + dx + dx;
01246 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01247 color3[0] = (color >> 16) & 0xff;
01248 color3[1] = (color >> 8) & 0xff;
01249 color3[2] = color & 0xff;
01250 } else {
01251 color3[0] = color & 0xff;
01252 color3[1] = (color >> 8) & 0xff;
01253 color3[2] = (color >> 16) & 0xff;
01254 }
01255 for (; pixel <= pixellast; pixel += pixx) {
01256 memcpy(pixel, color3, 3);
01257 }
01258 break;
01259 default:
01260 dx = dx + dx;
01261 pixellast = pixel + dx + dx;
01262 for (; pixel <= pixellast; pixel += pixx) {
01263 *(Uint32 *) pixel = color;
01264 }
01265 break;
01266 }
01267
01268
01269
01270
01271 if (SDL_MUSTLOCK(dst)) {
01272 SDL_UnlockSurface(dst);
01273 }
01274
01275
01276
01277
01278 result = 0;
01279
01280 } else {
01281
01282
01283
01284
01285 result = _HLineAlpha(dst, x1, x1 + dx, y, color);
01286 }
01287
01288 return (result);
01289 }
01290
01305 int hlineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01306 {
01307
01308
01309
01310 return (hlineColor(dst, x1, x2, y, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01311 }
01312
01324 int vlineColor(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color)
01325 {
01326 Sint16 left, right, top, bottom;
01327 Uint8 *pixel, *pixellast;
01328 int dy;
01329 int pixx, pixy;
01330 Sint16 h;
01331 Sint16 ytmp;
01332 int result = -1;
01333 Uint8 *colorptr;
01334
01335
01336
01337
01338 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01339 return(0);
01340 }
01341
01342
01343
01344
01345 if (y1 > y2) {
01346 ytmp = y1;
01347 y1 = y2;
01348 y2 = ytmp;
01349 }
01350
01351
01352
01353
01354
01355 left = dst->clip_rect.x;
01356 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01357 if ((x<left) || (x>right)) {
01358 return (0);
01359 }
01360 top = dst->clip_rect.y;
01361 if (y2<top) {
01362 return(0);
01363 }
01364 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01365 if (y1>bottom) {
01366 return(0);
01367 }
01368
01369
01370
01371
01372 if (y1 < top) {
01373 y1 = top;
01374 }
01375 if (y2 > bottom) {
01376 y2 = bottom;
01377 }
01378
01379
01380
01381
01382 h = y2 - y1;
01383
01384
01385
01386
01387 if ((color & 255) == 255) {
01388
01389
01390
01391
01392
01393
01394
01395
01396 colorptr = (Uint8 *) & color;
01397 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01398 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
01399 } else {
01400 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
01401 }
01402
01403
01404
01405
01406 if (SDL_MUSTLOCK(dst)) {
01407 if (SDL_LockSurface(dst) < 0) {
01408 return (-1);
01409 }
01410 }
01411
01412
01413
01414
01415 dy = h;
01416 pixx = dst->format->BytesPerPixel;
01417 pixy = dst->pitch;
01418 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x + pixy * (int) y1;
01419 pixellast = pixel + pixy * dy;
01420
01421
01422
01423
01424 switch (dst->format->BytesPerPixel) {
01425 case 1:
01426 for (; pixel <= pixellast; pixel += pixy) {
01427 *(Uint8 *) pixel = color;
01428 }
01429 break;
01430 case 2:
01431 for (; pixel <= pixellast; pixel += pixy) {
01432 *(Uint16 *) pixel = color;
01433 }
01434 break;
01435 case 3:
01436 for (; pixel <= pixellast; pixel += pixy) {
01437 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
01438 pixel[0] = (color >> 16) & 0xff;
01439 pixel[1] = (color >> 8) & 0xff;
01440 pixel[2] = color & 0xff;
01441 } else {
01442 pixel[0] = color & 0xff;
01443 pixel[1] = (color >> 8) & 0xff;
01444 pixel[2] = (color >> 16) & 0xff;
01445 }
01446 }
01447 break;
01448 default:
01449 for (; pixel <= pixellast; pixel += pixy) {
01450 *(Uint32 *) pixel = color;
01451 }
01452 break;
01453 }
01454
01455
01456 if (SDL_MUSTLOCK(dst)) {
01457 SDL_UnlockSurface(dst);
01458 }
01459
01460
01461
01462
01463 result = 0;
01464
01465 } else {
01466
01467
01468
01469
01470
01471 result = _VLineAlpha(dst, x, y1, y1 + h, color);
01472
01473 }
01474
01475 return (result);
01476 }
01477
01492 int vlineRGBA(SDL_Surface * dst, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01493 {
01494
01495
01496
01497 return (vlineColor(dst, x, y1, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01498 }
01499
01512 int rectangleColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
01513 {
01514 int result;
01515 Sint16 tmp;
01516
01517
01518 if (dst == NULL)
01519 {
01520 return -1;
01521 }
01522
01523
01524
01525
01526 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01527 return 0;
01528 }
01529
01530
01531
01532
01533 if (x1 == x2) {
01534 if (y1 == y2) {
01535 return (pixelColor(dst, x1, y1, color));
01536 } else {
01537 return (vlineColor(dst, x1, y1, y2, color));
01538 }
01539 } else {
01540 if (y1 == y2) {
01541 return (hlineColor(dst, x1, x2, y1, color));
01542 }
01543 }
01544
01545
01546
01547
01548 if (x1 > x2) {
01549 tmp = x1;
01550 x1 = x2;
01551 x2 = tmp;
01552 }
01553
01554
01555
01556
01557 if (y1 > y2) {
01558 tmp = y1;
01559 y1 = y2;
01560 y2 = tmp;
01561 }
01562
01563
01564
01565
01566 result = 0;
01567 result |= hlineColor(dst, x1, x2, y1, color);
01568 result |= hlineColor(dst, x1, x2, y2, color);
01569 y1 += 1;
01570 y2 -= 1;
01571 if (y1 <= y2) {
01572 result |= vlineColor(dst, x1, y1, y2, color);
01573 result |= vlineColor(dst, x2, y1, y2, color);
01574 }
01575
01576 return (result);
01577
01578 }
01579
01595 int rectangleRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01596 {
01597
01598
01599
01600 return (rectangleColor
01601 (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01602 }
01603
01617 int roundedRectangleColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint32 color)
01618 {
01619 int result;
01620 Sint16 w, h, tmp;
01621 Sint16 xx1, xx2, yy1, yy2;
01622
01623
01624
01625
01626 if (dst == NULL)
01627 {
01628 return -1;
01629 }
01630
01631
01632
01633
01634 if (rad < 0) {
01635 return -1;
01636 }
01637
01638
01639
01640
01641 if (rad == 0) {
01642 return rectangleColor(dst, x1, y1, x2, y2, color);
01643 }
01644
01645
01646
01647
01648 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01649 return 0;
01650 }
01651
01652
01653
01654
01655 if (x1 == x2) {
01656 if (y1 == y2) {
01657 return (pixelColor(dst, x1, y1, color));
01658 } else {
01659 return (vlineColor(dst, x1, y1, y2, color));
01660 }
01661 } else {
01662 if (y1 == y2) {
01663 return (hlineColor(dst, x1, x2, y1, color));
01664 }
01665 }
01666
01667
01668
01669
01670 if (x1 > x2) {
01671 tmp = x1;
01672 x1 = x2;
01673 x2 = tmp;
01674 }
01675
01676
01677
01678
01679 if (y1 > y2) {
01680 tmp = y1;
01681 y1 = y2;
01682 y2 = tmp;
01683 }
01684
01685
01686
01687
01688 w = x2 - x1;
01689 h = y2 - y1;
01690
01691
01692
01693
01694 if ((rad * 2) > w)
01695 {
01696 rad = w / 2;
01697 }
01698 if ((rad * 2) > h)
01699 {
01700 rad = h / 2;
01701 }
01702
01703
01704
01705
01706 result = 0;
01707 xx1 = x1 + rad;
01708 xx2 = x2 - rad;
01709 yy1 = y1 + rad;
01710 yy2 = y2 - rad;
01711 result |= arcColor(dst, xx1, yy1, rad, 180, 270, color);
01712 result |= arcColor(dst, xx2, yy1, rad, 270, 360, color);
01713 result |= arcColor(dst, xx1, yy2, rad, 90, 180, color);
01714 result |= arcColor(dst, xx2, yy2, rad, 0, 90, color);
01715
01716
01717
01718
01719 if (xx1 <= xx2) {
01720 result |= hlineColor(dst, xx1, xx2, y1, color);
01721 result |= hlineColor(dst, xx1, xx2, y2, color);
01722 }
01723 if (yy1 <= yy2) {
01724 result |= vlineColor(dst, x1, yy1, yy2, color);
01725 result |= vlineColor(dst, x2, yy1, yy2, color);
01726 }
01727
01728 return result;
01729 }
01730
01747 int roundedRectangleRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01748 {
01749
01750
01751
01752 return (roundedRectangleColor
01753 (dst, x1, y1, x2, y2, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01754 }
01755
01769 int roundedBoxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint32 color)
01770 {
01771 int result;
01772 Sint16 w, h, tmp;
01773 Sint16 xx1, xx2, yy1, yy2;
01774
01775
01776
01777
01778 if (dst == NULL)
01779 {
01780 return -1;
01781 }
01782
01783
01784
01785
01786 if (rad < 0) {
01787 return -1;
01788 }
01789
01790
01791
01792
01793 if (rad == 0) {
01794 return rectangleColor(dst, x1, y1, x2, y2, color);
01795 }
01796
01797
01798
01799
01800 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
01801 return 0;
01802 }
01803
01804
01805
01806
01807 if (x1 == x2) {
01808 if (y1 == y2) {
01809 return (pixelColor(dst, x1, y1, color));
01810 } else {
01811 return (vlineColor(dst, x1, y1, y2, color));
01812 }
01813 } else {
01814 if (y1 == y2) {
01815 return (hlineColor(dst, x1, x2, y1, color));
01816 }
01817 }
01818
01819
01820
01821
01822 if (x1 > x2) {
01823 tmp = x1;
01824 x1 = x2;
01825 x2 = tmp;
01826 }
01827
01828
01829
01830
01831 if (y1 > y2) {
01832 tmp = y1;
01833 y1 = y2;
01834 y2 = tmp;
01835 }
01836
01837
01838
01839
01840 w = x2 - x1;
01841 h = y2 - y1;
01842
01843
01844
01845
01846 if ((rad * 2) > w)
01847 {
01848 rad = w / 2;
01849 }
01850 if ((rad * 2) > h)
01851 {
01852 rad = h / 2;
01853 }
01854
01855
01856
01857
01858 result = 0;
01859 xx1 = x1 + rad;
01860 xx2 = x2 - rad;
01861 yy1 = y1 + rad;
01862 yy2 = y2 - rad;
01863 result |= filledPieColor(dst, xx1, yy1, rad, 180, 270, color);
01864 result |= filledPieColor(dst, xx2, yy1, rad, 270, 360, color);
01865 result |= filledPieColor(dst, xx1, yy2, rad, 90, 180, color);
01866 result |= filledPieColor(dst, xx2, yy2, rad, 0, 90, color);
01867
01868
01869
01870
01871 xx1++;
01872 xx2--;
01873 yy1++;
01874 yy2--;
01875 if (xx1 <= xx2) {
01876 result |= boxColor(dst, xx1, y1, xx2, y2, color);
01877 }
01878 if (yy1 <= yy2) {
01879 result |= boxColor(dst, x1, yy1, xx1-1, yy2, color);
01880 result |= boxColor(dst, xx2+1, yy1, x2, yy2, color);
01881 }
01882
01883 return result;
01884 }
01885
01902 int roundedBoxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2,
01903 Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
01904 {
01905
01906
01907
01908 return (roundedBoxColor
01909 (dst, x1, y1, x2, y2, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
01910 }
01911
01912
01913
01914
01915
01916
01917 #define CLIP_LEFT_EDGE 0x1
01918 #define CLIP_RIGHT_EDGE 0x2
01919 #define CLIP_BOTTOM_EDGE 0x4
01920 #define CLIP_TOP_EDGE 0x8
01921 #define CLIP_INSIDE(a) (!a)
01922 #define CLIP_REJECT(a,b) (a&b)
01923 #define CLIP_ACCEPT(a,b) (!(a|b))
01924
01937 static int _clipEncode(Sint16 x, Sint16 y, Sint16 left, Sint16 top, Sint16 right, Sint16 bottom)
01938 {
01939 int code = 0;
01940
01941 if (x < left) {
01942 code |= CLIP_LEFT_EDGE;
01943 } else if (x > right) {
01944 code |= CLIP_RIGHT_EDGE;
01945 }
01946 if (y < top) {
01947 code |= CLIP_TOP_EDGE;
01948 } else if (y > bottom) {
01949 code |= CLIP_BOTTOM_EDGE;
01950 }
01951 return code;
01952 }
01953
01963 static int _clipLine(SDL_Surface * dst, Sint16 * x1, Sint16 * y1, Sint16 * x2, Sint16 * y2)
01964 {
01965 Sint16 left, right, top, bottom;
01966 int code1, code2;
01967 int draw = 0;
01968 Sint16 swaptmp;
01969 float m;
01970
01971
01972
01973
01974 left = dst->clip_rect.x;
01975 right = dst->clip_rect.x + dst->clip_rect.w - 1;
01976 top = dst->clip_rect.y;
01977 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
01978
01979 while (1) {
01980 code1 = _clipEncode(*x1, *y1, left, top, right, bottom);
01981 code2 = _clipEncode(*x2, *y2, left, top, right, bottom);
01982 if (CLIP_ACCEPT(code1, code2)) {
01983 draw = 1;
01984 break;
01985 } else if (CLIP_REJECT(code1, code2))
01986 break;
01987 else {
01988 if (CLIP_INSIDE(code1)) {
01989 swaptmp = *x2;
01990 *x2 = *x1;
01991 *x1 = swaptmp;
01992 swaptmp = *y2;
01993 *y2 = *y1;
01994 *y1 = swaptmp;
01995 swaptmp = code2;
01996 code2 = code1;
01997 code1 = swaptmp;
01998 }
01999 if (*x2 != *x1) {
02000 m = (*y2 - *y1) / (float) (*x2 - *x1);
02001 } else {
02002 m = 1.0f;
02003 }
02004 if (code1 & CLIP_LEFT_EDGE) {
02005 *y1 += (Sint16) ((left - *x1) * m);
02006 *x1 = left;
02007 } else if (code1 & CLIP_RIGHT_EDGE) {
02008 *y1 += (Sint16) ((right - *x1) * m);
02009 *x1 = right;
02010 } else if (code1 & CLIP_BOTTOM_EDGE) {
02011 if (*x2 != *x1) {
02012 *x1 += (Sint16) ((bottom - *y1) / m);
02013 }
02014 *y1 = bottom;
02015 } else if (code1 & CLIP_TOP_EDGE) {
02016 if (*x2 != *x1) {
02017 *x1 += (Sint16) ((top - *y1) / m);
02018 }
02019 *y1 = top;
02020 }
02021 }
02022 }
02023
02024 return draw;
02025 }
02026
02039 int boxColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
02040 {
02041 Sint16 left, right, top, bottom;
02042 Uint8 *pixel, *pixellast;
02043 int x, dx;
02044 int dy;
02045 int pixx, pixy;
02046 Sint16 w, h, tmp;
02047 int result;
02048 Uint8 *colorptr;
02049
02050
02051
02052
02053 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
02054 return(0);
02055 }
02056
02057
02058
02059
02060
02061 if (x1 > x2) {
02062 tmp = x1;
02063 x1 = x2;
02064 x2 = tmp;
02065 }
02066 if (y1 > y2) {
02067 tmp = y1;
02068 y1 = y2;
02069 y2 = tmp;
02070 }
02071
02072
02073
02074
02075
02076 left = dst->clip_rect.x;
02077 if (x2<left) {
02078 return(0);
02079 }
02080 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02081 if (x1>right) {
02082 return(0);
02083 }
02084 top = dst->clip_rect.y;
02085 if (y2<top) {
02086 return(0);
02087 }
02088 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02089 if (y1>bottom) {
02090 return(0);
02091 }
02092
02093
02094 if (x1<left) {
02095 x1=left;
02096 } else if (x1>right) {
02097 x1=right;
02098 }
02099 if (x2<left) {
02100 x2=left;
02101 } else if (x2>right) {
02102 x2=right;
02103 }
02104 if (y1<top) {
02105 y1=top;
02106 } else if (y1>bottom) {
02107 y1=bottom;
02108 }
02109 if (y2<top) {
02110 y2=top;
02111 } else if (y2>bottom) {
02112 y2=bottom;
02113 }
02114
02115
02116
02117
02118 if (x1 == x2) {
02119 if (y1 == y2) {
02120 return (pixelColor(dst, x1, y1, color));
02121 } else {
02122 return (vlineColor(dst, x1, y1, y2, color));
02123 }
02124 }
02125 if (y1 == y2) {
02126 return (hlineColor(dst, x1, x2, y1, color));
02127 }
02128
02129
02130
02131
02132 w = x2 - x1;
02133 h = y2 - y1;
02134
02135
02136
02137
02138 if ((color & 255) == 255) {
02139
02140
02141
02142
02143
02144
02145
02146
02147 colorptr = (Uint8 *) & color;
02148 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02149 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
02150 } else {
02151 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
02152 }
02153
02154
02155
02156
02157 if (SDL_MUSTLOCK(dst)) {
02158 if (SDL_LockSurface(dst) < 0) {
02159 return (-1);
02160 }
02161 }
02162
02163
02164
02165
02166 dx = w;
02167 dy = h;
02168 pixx = dst->format->BytesPerPixel;
02169 pixy = dst->pitch;
02170 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
02171 pixellast = pixel + pixx * dx + pixy * dy;
02172 dx++;
02173
02174
02175
02176
02177 switch (dst->format->BytesPerPixel) {
02178 case 1:
02179 for (; pixel <= pixellast; pixel += pixy) {
02180 memset(pixel, (Uint8) color, dx);
02181 }
02182 break;
02183 case 2:
02184 pixy -= (pixx * dx);
02185 for (; pixel <= pixellast; pixel += pixy) {
02186 for (x = 0; x < dx; x++) {
02187 *(Uint16*) pixel = color;
02188 pixel += pixx;
02189 }
02190 }
02191 break;
02192 case 3:
02193 pixy -= (pixx * dx);
02194 for (; pixel <= pixellast; pixel += pixy) {
02195 for (x = 0; x < dx; x++) {
02196 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02197 pixel[0] = (color >> 16) & 0xff;
02198 pixel[1] = (color >> 8) & 0xff;
02199 pixel[2] = color & 0xff;
02200 } else {
02201 pixel[0] = color & 0xff;
02202 pixel[1] = (color >> 8) & 0xff;
02203 pixel[2] = (color >> 16) & 0xff;
02204 }
02205 pixel += pixx;
02206 }
02207 }
02208 break;
02209 default:
02210 pixy -= (pixx * dx);
02211 for (; pixel <= pixellast; pixel += pixy) {
02212 for (x = 0; x < dx; x++) {
02213 *(Uint32 *) pixel = color;
02214 pixel += pixx;
02215 }
02216 }
02217 break;
02218 }
02219
02220
02221 if (SDL_MUSTLOCK(dst)) {
02222 SDL_UnlockSurface(dst);
02223 }
02224
02225 result = 0;
02226
02227 } else {
02228
02229 result = filledRectAlpha(dst, x1, y1, x1 + w, y1 + h, color);
02230
02231 }
02232
02233 return (result);
02234 }
02235
02251 int boxRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02252 {
02253
02254
02255
02256 return (boxColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02257 }
02258
02259
02260
02261
02262
02263
02264
02265 #define ABS(a) (((a)<0) ? -(a) : (a))
02266
02279 int lineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
02280 {
02281 int pixx, pixy;
02282 int x, y;
02283 int dx, dy;
02284 int ax, ay;
02285 int sx, sy;
02286 int swaptmp;
02287 Uint8 *pixel;
02288 Uint8 *colorptr;
02289
02290
02291
02292
02293 if (!(_clipLine(dst, &x1, &y1, &x2, &y2))) {
02294 return (0);
02295 }
02296
02297
02298
02299
02300 if (x1 == x2) {
02301 if (y1 < y2) {
02302 return (vlineColor(dst, x1, y1, y2, color));
02303 } else if (y1 > y2) {
02304 return (vlineColor(dst, x1, y2, y1, color));
02305 } else {
02306 return (pixelColor(dst, x1, y1, color));
02307 }
02308 }
02309 if (y1 == y2) {
02310 if (x1 < x2) {
02311 return (hlineColor(dst, x1, x2, y1, color));
02312 } else if (x1 > x2) {
02313 return (hlineColor(dst, x2, x1, y1, color));
02314 }
02315 }
02316
02317
02318
02319
02320 dx = x2 - x1;
02321 dy = y2 - y1;
02322 sx = (dx >= 0) ? 1 : -1;
02323 sy = (dy >= 0) ? 1 : -1;
02324
02325
02326 if (SDL_MUSTLOCK(dst)) {
02327 if (SDL_LockSurface(dst) < 0) {
02328 return (-1);
02329 }
02330 }
02331
02332
02333
02334
02335 if ((color & 255) == 255) {
02336
02337
02338
02339
02340
02341
02342
02343
02344 colorptr = (Uint8 *) & color;
02345 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02346 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
02347 } else {
02348 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
02349 }
02350
02351
02352
02353
02354 dx = sx * dx + 1;
02355 dy = sy * dy + 1;
02356 pixx = dst->format->BytesPerPixel;
02357 pixy = dst->pitch;
02358 pixel = ((Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y1;
02359 pixx *= sx;
02360 pixy *= sy;
02361 if (dx < dy) {
02362 swaptmp = dx;
02363 dx = dy;
02364 dy = swaptmp;
02365 swaptmp = pixx;
02366 pixx = pixy;
02367 pixy = swaptmp;
02368 }
02369
02370
02371
02372
02373 x = 0;
02374 y = 0;
02375 switch (dst->format->BytesPerPixel) {
02376 case 1:
02377 for (; x < dx; x++, pixel += pixx) {
02378 *pixel = color;
02379 y += dy;
02380 if (y >= dx) {
02381 y -= dx;
02382 pixel += pixy;
02383 }
02384 }
02385 break;
02386 case 2:
02387 for (; x < dx; x++, pixel += pixx) {
02388 *(Uint16 *) pixel = color;
02389 y += dy;
02390 if (y >= dx) {
02391 y -= dx;
02392 pixel += pixy;
02393 }
02394 }
02395 break;
02396 case 3:
02397 for (; x < dx; x++, pixel += pixx) {
02398 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02399 pixel[0] = (color >> 16) & 0xff;
02400 pixel[1] = (color >> 8) & 0xff;
02401 pixel[2] = color & 0xff;
02402 } else {
02403 pixel[0] = color & 0xff;
02404 pixel[1] = (color >> 8) & 0xff;
02405 pixel[2] = (color >> 16) & 0xff;
02406 }
02407 y += dy;
02408 if (y >= dx) {
02409 y -= dx;
02410 pixel += pixy;
02411 }
02412 }
02413 break;
02414 default:
02415 for (; x < dx; x++, pixel += pixx) {
02416 *(Uint32 *) pixel = color;
02417 y += dy;
02418 if (y >= dx) {
02419 y -= dx;
02420 pixel += pixy;
02421 }
02422 }
02423 break;
02424 }
02425
02426 } else {
02427
02428
02429
02430
02431
02432 ax = ABS(dx) << 1;
02433 ay = ABS(dy) << 1;
02434 x = x1;
02435 y = y1;
02436 if (ax > ay) {
02437 int d = ay - (ax >> 1);
02438
02439 while (x != x2) {
02440 pixelColorNolock (dst, x, y, color);
02441 if (d > 0 || (d == 0 && sx == 1)) {
02442 y += sy;
02443 d -= ax;
02444 }
02445 x += sx;
02446 d += ay;
02447 }
02448 } else {
02449 int d = ax - (ay >> 1);
02450
02451 while (y != y2) {
02452 pixelColorNolock (dst, x, y, color);
02453 if (d > 0 || ((d == 0) && (sy == 1))) {
02454 x += sx;
02455 d -= ay;
02456 }
02457 y += sy;
02458 d += ax;
02459 }
02460 }
02461 pixelColorNolock (dst, x, y, color);
02462
02463 }
02464
02465
02466 if (SDL_MUSTLOCK(dst)) {
02467 SDL_UnlockSurface(dst);
02468 }
02469
02470 return (0);
02471 }
02472
02488 int lineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02489 {
02490
02491
02492
02493 return (lineColor(dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
02494 }
02495
02496
02497
02498 #define AAlevels 256
02499 #define AAbits 8
02500
02521 int _aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color, int draw_endpoint)
02522 {
02523 Sint32 xx0, yy0, xx1, yy1;
02524 int result;
02525 Uint32 intshift, erracc, erradj;
02526 Uint32 erracctmp, wgt, wgtcompmask;
02527 int dx, dy, tmp, xdir, y0p1, x0pxdir;
02528
02529
02530
02531
02532 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
02533 return(0);
02534 }
02535
02536
02537
02538
02539 if (!(_clipLine(dst, &x1, &y1, &x2, &y2))) {
02540 return (0);
02541 }
02542
02543
02544
02545
02546 xx0 = x1;
02547 yy0 = y1;
02548 xx1 = x2;
02549 yy1 = y2;
02550
02551
02552
02553
02554 if (yy0 > yy1) {
02555 tmp = yy0;
02556 yy0 = yy1;
02557 yy1 = tmp;
02558 tmp = xx0;
02559 xx0 = xx1;
02560 xx1 = tmp;
02561 }
02562
02563
02564
02565
02566 dx = xx1 - xx0;
02567 dy = yy1 - yy0;
02568
02569
02570
02571
02572 if (dx == 0) {
02573
02574
02575
02576 if (draw_endpoint)
02577 {
02578 return (vlineColor(dst, x1, y1, y2, color));
02579 } else {
02580 if (dy>0) {
02581 return (vlineColor(dst, x1, yy0, yy0+dy, color));
02582 } else {
02583 return (pixelColor(dst, x1, y1, color));
02584 }
02585 }
02586 } else if (dy == 0) {
02587
02588
02589
02590 if (draw_endpoint)
02591 {
02592 return (hlineColor(dst, x1, x2, y1, color));
02593 } else {
02594 if (dx>0) {
02595 return (hlineColor(dst, xx0, xx0+dx, y1, color));
02596 } else {
02597 return (pixelColor(dst, x1, y1, color));
02598 }
02599 }
02600 } else if ((dx == dy) && (draw_endpoint)) {
02601
02602
02603
02604 return (lineColor(dst, x1, y1, x2, y2, color));
02605 }
02606
02607
02608
02609
02610 if (dx >= 0) {
02611 xdir = 1;
02612 } else {
02613 xdir = -1;
02614 dx = (-dx);
02615 }
02616
02617
02618
02619
02620 result = 0;
02621
02622
02623
02624
02625 erracc = 0;
02626
02627
02628
02629
02630 intshift = 32 - AAbits;
02631
02632
02633
02634
02635 wgtcompmask = AAlevels - 1;
02636
02637
02638 if (SDL_MUSTLOCK(dst)) {
02639 if (SDL_LockSurface(dst) < 0) {
02640 return (-1);
02641 }
02642 }
02643
02644
02645
02646
02647 result |= pixelColorNolock(dst, x1, y1, color);
02648
02649
02650
02651
02652 if (dy > dx) {
02653
02654
02655
02656
02657
02658
02659
02660
02661
02662 erradj = ((dx << 16) / dy) << 16;
02663
02664
02665
02666
02667 x0pxdir = xx0 + xdir;
02668 while (--dy) {
02669 erracctmp = erracc;
02670 erracc += erradj;
02671 if (erracc <= erracctmp) {
02672
02673
02674
02675 xx0 = x0pxdir;
02676 x0pxdir += xdir;
02677 }
02678 yy0++;
02679
02680
02681
02682
02683
02684
02685 wgt = (erracc >> intshift) & 255;
02686 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
02687 result |= pixelColorWeightNolock (dst, x0pxdir, yy0, color, wgt);
02688 }
02689
02690 } else {
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700 erradj = ((dy << 16) / dx) << 16;
02701
02702
02703
02704
02705 y0p1 = yy0 + 1;
02706 while (--dx) {
02707
02708 erracctmp = erracc;
02709 erracc += erradj;
02710 if (erracc <= erracctmp) {
02711
02712
02713
02714 yy0 = y0p1;
02715 y0p1++;
02716 }
02717 xx0 += xdir;
02718
02719
02720
02721
02722
02723 wgt = (erracc >> intshift) & 255;
02724 result |= pixelColorWeightNolock (dst, xx0, yy0, color, 255 - wgt);
02725 result |= pixelColorWeightNolock (dst, xx0, y0p1, color, wgt);
02726 }
02727 }
02728
02729
02730
02731
02732 if (draw_endpoint) {
02733
02734
02735
02736
02737 result |= pixelColorNolock (dst, x2, y2, color);
02738 }
02739
02740
02741 if (SDL_MUSTLOCK(dst)) {
02742 SDL_UnlockSurface(dst);
02743 }
02744
02745 return (result);
02746 }
02747
02760 int aalineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color)
02761 {
02762 return (_aalineColor(dst, x1, y1, x2, y2, color, 1));
02763 }
02764
02780 int aalineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
02781 {
02782 return (_aalineColor
02783 (dst, x1, y1, x2, y2, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
02784 }
02785
02786
02787
02788
02804 int circleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
02805 {
02806 Sint16 left, right, top, bottom;
02807 int result;
02808 Sint16 x1, y1, x2, y2;
02809 Sint16 cx = 0;
02810 Sint16 cy = rad;
02811 Sint16 ocx = (Sint16) 0xffff;
02812 Sint16 ocy = (Sint16) 0xffff;
02813 Sint16 df = 1 - rad;
02814 Sint16 d_e = 3;
02815 Sint16 d_se = -2 * rad + 5;
02816 Sint16 xpcx, xmcx, xpcy, xmcy;
02817 Sint16 ypcy, ymcy, ypcx, ymcx;
02818 Uint8 *colorptr;
02819
02820
02821
02822
02823 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
02824 return(0);
02825 }
02826
02827
02828
02829
02830 if (rad < 0) {
02831 return (-1);
02832 }
02833
02834
02835
02836
02837 if (rad == 0) {
02838 return (pixelColor(dst, x, y, color));
02839 }
02840
02841
02842
02843
02844
02845 x2 = x + rad;
02846 left = dst->clip_rect.x;
02847 if (x2<left) {
02848 return(0);
02849 }
02850 x1 = x - rad;
02851 right = dst->clip_rect.x + dst->clip_rect.w - 1;
02852 if (x1>right) {
02853 return(0);
02854 }
02855 y2 = y + rad;
02856 top = dst->clip_rect.y;
02857 if (y2<top) {
02858 return(0);
02859 }
02860 y1 = y - rad;
02861 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
02862 if (y1>bottom) {
02863 return(0);
02864 }
02865
02866
02867
02868
02869 result = 0;
02870
02871
02872 if (SDL_MUSTLOCK(dst)) {
02873 if (SDL_LockSurface(dst) < 0) {
02874 return (-1);
02875 }
02876 }
02877
02878
02879
02880
02881 if ((color & 255) == 255) {
02882
02883
02884
02885
02886
02887
02888
02889
02890 colorptr = (Uint8 *) & color;
02891 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
02892 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
02893 } else {
02894 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
02895 }
02896
02897
02898
02899
02900 do {
02901 ypcy = y + cy;
02902 ymcy = y - cy;
02903 if (cx > 0) {
02904 xpcx = x + cx;
02905 xmcx = x - cx;
02906 result |= fastPixelColorNolock(dst, xmcx, ypcy, color);
02907 result |= fastPixelColorNolock(dst, xpcx, ypcy, color);
02908 result |= fastPixelColorNolock(dst, xmcx, ymcy, color);
02909 result |= fastPixelColorNolock(dst, xpcx, ymcy, color);
02910 } else {
02911 result |= fastPixelColorNolock(dst, x, ymcy, color);
02912 result |= fastPixelColorNolock(dst, x, ypcy, color);
02913 }
02914 xpcy = x + cy;
02915 xmcy = x - cy;
02916 if ((cx > 0) && (cx != cy)) {
02917 ypcx = y + cx;
02918 ymcx = y - cx;
02919 result |= fastPixelColorNolock(dst, xmcy, ypcx, color);
02920 result |= fastPixelColorNolock(dst, xpcy, ypcx, color);
02921 result |= fastPixelColorNolock(dst, xmcy, ymcx, color);
02922 result |= fastPixelColorNolock(dst, xpcy, ymcx, color);
02923 } else if (cx == 0) {
02924 result |= fastPixelColorNolock(dst, xmcy, y, color);
02925 result |= fastPixelColorNolock(dst, xpcy, y, color);
02926 }
02927
02928
02929
02930 if (df < 0) {
02931 df += d_e;
02932 d_e += 2;
02933 d_se += 2;
02934 } else {
02935 df += d_se;
02936 d_e += 2;
02937 d_se += 4;
02938 cy--;
02939 }
02940 cx++;
02941 } while (cx <= cy);
02942
02943
02944
02945
02946 SDL_UnlockSurface(dst);
02947
02948 } else {
02949
02950
02951
02952
02953
02954 do {
02955
02956
02957
02958 ypcy = y + cy;
02959 ymcy = y - cy;
02960 if (cx > 0) {
02961 xpcx = x + cx;
02962 xmcx = x - cx;
02963 result |= pixelColorNolock (dst, xmcx, ypcy, color);
02964 result |= pixelColorNolock (dst, xpcx, ypcy, color);
02965 result |= pixelColorNolock (dst, xmcx, ymcy, color);
02966 result |= pixelColorNolock (dst, xpcx, ymcy, color);
02967 } else {
02968 result |= pixelColorNolock (dst, x, ymcy, color);
02969 result |= pixelColorNolock (dst, x, ypcy, color);
02970 }
02971 xpcy = x + cy;
02972 xmcy = x - cy;
02973 if ((cx > 0) && (cx != cy)) {
02974 ypcx = y + cx;
02975 ymcx = y - cx;
02976 result |= pixelColorNolock (dst, xmcy, ypcx, color);
02977 result |= pixelColorNolock (dst, xpcy, ypcx, color);
02978 result |= pixelColorNolock (dst, xmcy, ymcx, color);
02979 result |= pixelColorNolock (dst, xpcy, ymcx, color);
02980 } else if (cx == 0) {
02981 result |= pixelColorNolock (dst, xmcy, y, color);
02982 result |= pixelColorNolock (dst, xpcy, y, color);
02983 }
02984
02985
02986
02987 if (df < 0) {
02988 df += d_e;
02989 d_e += 2;
02990 d_se += 2;
02991 } else {
02992 df += d_se;
02993 d_e += 2;
02994 d_se += 4;
02995 cy--;
02996 }
02997 cx++;
02998 } while (cx <= cy);
02999
03000 }
03001
03002
03003 if (SDL_MUSTLOCK(dst)) {
03004 SDL_UnlockSurface(dst);
03005 }
03006
03007 return (result);
03008 }
03009
03024 int circleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03025 {
03026
03027
03028
03029 return (circleColor(dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03030 }
03031
03032
03033
03051 int arcColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
03052 {
03053 Sint16 left, right, top, bottom;
03054 int result;
03055 Sint16 x1, y1, x2, y2;
03056 Sint16 cx = 0;
03057 Sint16 cy = rad;
03058 Sint16 ocx = (Sint16) 0xffff;
03059 Sint16 ocy = (Sint16) 0xffff;
03060 Sint16 df = 1 - rad;
03061 Sint16 d_e = 3;
03062 Sint16 d_se = -2 * rad + 5;
03063 Sint16 xpcx, xmcx, xpcy, xmcy;
03064 Sint16 ypcy, ymcy, ypcx, ymcx;
03065 Uint8 *colorptr;
03066 Uint8 drawoct;
03067 int startoct, endoct, oct, stopval_start, stopval_end;
03068 double temp;
03069
03070
03071
03072
03073 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
03074 return(0);
03075 }
03076
03077
03078
03079
03080 if (rad < 0) {
03081 return (-1);
03082 }
03083
03084
03085
03086
03087 if (rad == 0) {
03088 return (pixelColor(dst, x, y, color));
03089 }
03090
03091
03092
03093
03094
03095 x2 = x + rad;
03096 left = dst->clip_rect.x;
03097 if (x2<left) {
03098 return(0);
03099 }
03100 x1 = x - rad;
03101 right = dst->clip_rect.x + dst->clip_rect.w - 1;
03102 if (x1>right) {
03103 return(0);
03104 }
03105 y2 = y + rad;
03106 top = dst->clip_rect.y;
03107 if (y2<top) {
03108 return(0);
03109 }
03110 y1 = y - rad;
03111 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
03112 if (y1>bottom) {
03113 return(0);
03114 }
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132 drawoct = 0;
03133
03134
03135
03136
03137 start %= 360;
03138 end %= 360;
03139
03140 while (start < 0) start += 360;
03141 while (end < 0) end += 360;
03142 start %= 360;
03143 end %= 360;
03144
03145
03146 startoct = start / 45;
03147 endoct = end / 45;
03148 oct = startoct - 1;
03149
03150
03151
03152 do {
03153 oct = (oct + 1) % 8;
03154
03155 if (oct == startoct) {
03156
03157 switch (oct)
03158 {
03159 case 0:
03160 case 3:
03161 temp = sin(start * M_PI / 180);
03162 break;
03163 case 1:
03164 case 6:
03165 temp = cos(start * M_PI / 180);
03166 break;
03167 case 2:
03168 case 5:
03169 temp = -cos(start * M_PI / 180);
03170 break;
03171 case 4:
03172 case 7:
03173 temp = -sin(start * M_PI / 180);
03174 break;
03175 }
03176 temp *= rad;
03177 stopval_start = (int)temp;
03178
03179
03180
03181
03182
03183 if (oct % 2) drawoct |= (1 << oct);
03184 else drawoct &= 255 - (1 << oct);
03185 }
03186 if (oct == endoct) {
03187
03188 switch (oct)
03189 {
03190 case 0:
03191 case 3:
03192 temp = sin(end * M_PI / 180);
03193 break;
03194 case 1:
03195 case 6:
03196 temp = cos(end * M_PI / 180);
03197 break;
03198 case 2:
03199 case 5:
03200 temp = -cos(end * M_PI / 180);
03201 break;
03202 case 4:
03203 case 7:
03204 temp = -sin(end * M_PI / 180);
03205 break;
03206 }
03207 temp *= rad;
03208 stopval_end = (int)temp;
03209
03210
03211 if (startoct == endoct) {
03212
03213
03214 if (start > end) {
03215
03216
03217 drawoct = 255;
03218 } else {
03219 drawoct &= 255 - (1 << oct);
03220 }
03221 }
03222 else if (oct % 2) drawoct &= 255 - (1 << oct);
03223 else drawoct |= (1 << oct);
03224 } else if (oct != startoct) {
03225 drawoct |= (1 << oct);
03226 }
03227 } while (oct != endoct);
03228
03229
03230
03231
03232 if (SDL_MUSTLOCK(dst)) {
03233 if (SDL_LockSurface(dst) < 0) {
03234 return (-1);
03235 }
03236 }
03237
03238
03239
03240
03241 result = 0;
03242
03243
03244
03245
03246 if ((color & 255) == 255) {
03247
03248
03249
03250
03251
03252
03253
03254
03255 colorptr = (Uint8 *) & color;
03256 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
03257 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
03258 } else {
03259 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
03260 }
03261
03262
03263
03264
03265 do {
03266 ypcy = y + cy;
03267 ymcy = y - cy;
03268 if (cx > 0) {
03269 xpcx = x + cx;
03270 xmcx = x - cx;
03271
03272 if (drawoct & 4) result |= fastPixelColorNolock(dst, xmcx, ypcy, color);
03273 if (drawoct & 2) result |= fastPixelColorNolock(dst, xpcx, ypcy, color);
03274 if (drawoct & 32) result |= fastPixelColorNolock(dst, xmcx, ymcy, color);
03275 if (drawoct & 64) result |= fastPixelColorNolock(dst, xpcx, ymcy, color);
03276 } else {
03277 if (drawoct & 6) result |= fastPixelColorNolock(dst, x, ypcy, color);
03278 if (drawoct & 96) result |= fastPixelColorNolock(dst, x, ymcy, color);
03279 }
03280
03281 xpcy = x + cy;
03282 xmcy = x - cy;
03283 if (cx > 0 && cx != cy) {
03284 ypcx = y + cx;
03285 ymcx = y - cx;
03286 if (drawoct & 8) result |= fastPixelColorNolock(dst, xmcy, ypcx, color);
03287 if (drawoct & 1) result |= fastPixelColorNolock(dst, xpcy, ypcx, color);
03288 if (drawoct & 16) result |= fastPixelColorNolock(dst, xmcy, ymcx, color);
03289 if (drawoct & 128) result |= fastPixelColorNolock(dst, xpcy, ymcx, color);
03290 } else if (cx == 0) {
03291 if (drawoct & 24) result |= fastPixelColorNolock(dst, xmcy, y, color);
03292 if (drawoct & 129) result |= fastPixelColorNolock(dst, xpcy, y, color);
03293 }
03294
03295
03296
03297
03298 if (stopval_start == cx) {
03299
03300 if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct);
03301 else drawoct |= (1 << startoct);
03302 }
03303 if (stopval_end == cx) {
03304 if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct);
03305 else drawoct |= (1 << endoct);
03306 }
03307
03308
03309
03310
03311 if (df < 0) {
03312 df += d_e;
03313 d_e += 2;
03314 d_se += 2;
03315 } else {
03316 df += d_se;
03317 d_e += 2;
03318 d_se += 4;
03319 cy--;
03320 }
03321 cx++;
03322 } while (cx <= cy);
03323
03324
03325
03326
03327 SDL_UnlockSurface(dst);
03328
03329 } else {
03330
03331
03332
03333
03334
03335 do {
03336 ypcy = y + cy;
03337 ymcy = y - cy;
03338 if (cx > 0) {
03339 xpcx = x + cx;
03340 xmcx = x - cx;
03341
03342
03343 if (drawoct & 4) result |= pixelColorNolock(dst, xmcx, ypcy, color);
03344 if (drawoct & 2) result |= pixelColorNolock(dst, xpcx, ypcy, color);
03345 if (drawoct & 32) result |= pixelColorNolock(dst, xmcx, ymcy, color);
03346 if (drawoct & 64) result |= pixelColorNolock(dst, xpcx, ymcy, color);
03347 } else {
03348 if (drawoct & 96) result |= pixelColorNolock(dst, x, ymcy, color);
03349 if (drawoct & 6) result |= pixelColorNolock(dst, x, ypcy, color);
03350 }
03351
03352 xpcy = x + cy;
03353 xmcy = x - cy;
03354 if (cx > 0 && cx != cy) {
03355 ypcx = y + cx;
03356 ymcx = y - cx;
03357 if (drawoct & 8) result |= pixelColorNolock(dst, xmcy, ypcx, color);
03358 if (drawoct & 1) result |= pixelColorNolock(dst, xpcy, ypcx, color);
03359 if (drawoct & 16) result |= pixelColorNolock(dst, xmcy, ymcx, color);
03360 if (drawoct & 128) result |= pixelColorNolock(dst, xpcy, ymcx, color);
03361 } else if (cx == 0) {
03362 if (drawoct & 24) result |= pixelColorNolock(dst, xmcy, y, color);
03363 if (drawoct & 129) result |= pixelColorNolock(dst, xpcy, y, color);
03364 }
03365
03366
03367
03368
03369 if (stopval_start == cx) {
03370
03371
03372 if (drawoct & (1 << startoct)) drawoct &= 255 - (1 << startoct);
03373 else drawoct |= (1 << startoct);
03374 }
03375 if (stopval_end == cx) {
03376 if (drawoct & (1 << endoct)) drawoct &= 255 - (1 << endoct);
03377 else drawoct |= (1 << endoct);
03378 }
03379
03380
03381
03382
03383 if (df < 0) {
03384 df += d_e;
03385 d_e += 2;
03386 d_se += 2;
03387 } else {
03388 df += d_se;
03389 d_e += 2;
03390 d_se += 4;
03391 cy--;
03392 }
03393 cx++;
03394 } while (cx <= cy);
03395
03396 }
03397
03398
03399 if (SDL_MUSTLOCK(dst)) {
03400 SDL_UnlockSurface(dst);
03401 }
03402
03403 return (result);
03404 }
03405
03422 int arcRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03423 {
03424
03425
03426
03427 return (arcColor(dst, x, y, rad, start, end, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03428 }
03429
03430
03431
03432
03446 int aacircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
03447 {
03448 return (aaellipseColor(dst, x, y, rad, rad, color));
03449 }
03450
03465 int aacircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03466 {
03467
03468
03469
03470 return (aaellipseColor
03471 (dst, x, y, rad, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03472 }
03473
03474
03475
03490 int filledCircleColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint32 color)
03491 {
03492 Sint16 left, right, top, bottom;
03493 int result;
03494 Sint16 x1, y1, x2, y2;
03495 Sint16 cx = 0;
03496 Sint16 cy = rad;
03497 Sint16 ocx = (Sint16) 0xffff;
03498 Sint16 ocy = (Sint16) 0xffff;
03499 Sint16 df = 1 - rad;
03500 Sint16 d_e = 3;
03501 Sint16 d_se = -2 * rad + 5;
03502 Sint16 xpcx, xmcx, xpcy, xmcy;
03503 Sint16 ypcy, ymcy, ypcx, ymcx;
03504
03505
03506
03507
03508 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
03509 return(0);
03510 }
03511
03512
03513
03514
03515 if (rad < 0) {
03516 return (-1);
03517 }
03518
03519
03520
03521
03522 if (rad == 0) {
03523 return (pixelColor(dst, x, y, color));
03524 }
03525
03526
03527
03528
03529
03530 x2 = x + rad;
03531 left = dst->clip_rect.x;
03532 if (x2<left) {
03533 return(0);
03534 }
03535 x1 = x - rad;
03536 right = dst->clip_rect.x + dst->clip_rect.w - 1;
03537 if (x1>right) {
03538 return(0);
03539 }
03540 y2 = y + rad;
03541 top = dst->clip_rect.y;
03542 if (y2<top) {
03543 return(0);
03544 }
03545 y1 = y - rad;
03546 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
03547 if (y1>bottom) {
03548 return(0);
03549 }
03550
03551
03552
03553
03554 result = 0;
03555 do {
03556 xpcx = x + cx;
03557 xmcx = x - cx;
03558 xpcy = x + cy;
03559 xmcy = x - cy;
03560 if (ocy != cy) {
03561 if (cy > 0) {
03562 ypcy = y + cy;
03563 ymcy = y - cy;
03564 result |= hlineColor(dst, xmcx, xpcx, ypcy, color);
03565 result |= hlineColor(dst, xmcx, xpcx, ymcy, color);
03566 } else {
03567 result |= hlineColor(dst, xmcx, xpcx, y, color);
03568 }
03569 ocy = cy;
03570 }
03571 if (ocx != cx) {
03572 if (cx != cy) {
03573 if (cx > 0) {
03574 ypcx = y + cx;
03575 ymcx = y - cx;
03576 result |= hlineColor(dst, xmcy, xpcy, ymcx, color);
03577 result |= hlineColor(dst, xmcy, xpcy, ypcx, color);
03578 } else {
03579 result |= hlineColor(dst, xmcy, xpcy, y, color);
03580 }
03581 }
03582 ocx = cx;
03583 }
03584
03585
03586
03587 if (df < 0) {
03588 df += d_e;
03589 d_e += 2;
03590 d_se += 2;
03591 } else {
03592 df += d_se;
03593 d_e += 2;
03594 d_se += 4;
03595 cy--;
03596 }
03597 cx++;
03598 } while (cx <= cy);
03599
03600 return (result);
03601 }
03602
03617 int filledCircleRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03618 {
03619
03620
03621
03622 return (filledCircleColor
03623 (dst, x, y, rad, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03624 }
03625
03626
03627
03643 int ellipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
03644 {
03645 Sint16 left, right, top, bottom;
03646 int result;
03647 Sint16 x1, y1, x2, y2;
03648 int ix, iy;
03649 int h, i, j, k;
03650 int oh, oi, oj, ok;
03651 int xmh, xph, ypk, ymk;
03652 int xmi, xpi, ymj, ypj;
03653 int xmj, xpj, ymi, ypi;
03654 int xmk, xpk, ymh, yph;
03655 Uint8 *colorptr;
03656
03657
03658
03659
03660 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
03661 return(0);
03662 }
03663
03664
03665
03666
03667 if ((rx < 0) || (ry < 0)) {
03668 return (-1);
03669 }
03670
03671
03672
03673
03674 if (rx == 0) {
03675 return (vlineColor(dst, x, y - ry, y + ry, color));
03676 }
03677
03678
03679
03680 if (ry == 0) {
03681 return (hlineColor(dst, x - rx, x + rx, y, color));
03682 }
03683
03684
03685
03686
03687
03688 x2 = x + rx;
03689 left = dst->clip_rect.x;
03690 if (x2<left) {
03691 return(0);
03692 }
03693 x1 = x - rx;
03694 right = dst->clip_rect.x + dst->clip_rect.w - 1;
03695 if (x1>right) {
03696 return(0);
03697 }
03698 y2 = y + ry;
03699 top = dst->clip_rect.y;
03700 if (y2<top) {
03701 return(0);
03702 }
03703 y1 = y - ry;
03704 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
03705 if (y1>bottom) {
03706 return(0);
03707 }
03708
03709
03710
03711
03712 oh = oi = oj = ok = 0xFFFF;
03713
03714
03715
03716
03717 result = 0;
03718
03719
03720 if (SDL_MUSTLOCK(dst)) {
03721 if (SDL_LockSurface(dst) < 0) {
03722 return (-1);
03723 }
03724 }
03725
03726
03727
03728
03729 if ((color & 255) == 255) {
03730
03731
03732
03733
03734
03735
03736
03737
03738 colorptr = (Uint8 *) & color;
03739 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
03740 color = SDL_MapRGBA(dst->format, colorptr[0], colorptr[1], colorptr[2], colorptr[3]);
03741 } else {
03742 color = SDL_MapRGBA(dst->format, colorptr[3], colorptr[2], colorptr[1], colorptr[0]);
03743 }
03744
03745
03746 if (rx > ry) {
03747 ix = 0;
03748 iy = rx * 64;
03749
03750 do {
03751 h = (ix + 32) >> 6;
03752 i = (iy + 32) >> 6;
03753 j = (h * ry) / rx;
03754 k = (i * ry) / rx;
03755
03756 if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
03757 xph = x + h;
03758 xmh = x - h;
03759 if (k > 0) {
03760 ypk = y + k;
03761 ymk = y - k;
03762 result |= fastPixelColorNolock(dst, xmh, ypk, color);
03763 result |= fastPixelColorNolock(dst, xph, ypk, color);
03764 result |= fastPixelColorNolock(dst, xmh, ymk, color);
03765 result |= fastPixelColorNolock(dst, xph, ymk, color);
03766 } else {
03767 result |= fastPixelColorNolock(dst, xmh, y, color);
03768 result |= fastPixelColorNolock(dst, xph, y, color);
03769 }
03770 ok = k;
03771 xpi = x + i;
03772 xmi = x - i;
03773 if (j > 0) {
03774 ypj = y + j;
03775 ymj = y - j;
03776 result |= fastPixelColorNolock(dst, xmi, ypj, color);
03777 result |= fastPixelColorNolock(dst, xpi, ypj, color);
03778 result |= fastPixelColorNolock(dst, xmi, ymj, color);
03779 result |= fastPixelColorNolock(dst, xpi, ymj, color);
03780 } else {
03781 result |= fastPixelColorNolock(dst, xmi, y, color);
03782 result |= fastPixelColorNolock(dst, xpi, y, color);
03783 }
03784 oj = j;
03785 }
03786
03787 ix = ix + iy / rx;
03788 iy = iy - ix / rx;
03789
03790 } while (i > h);
03791 } else {
03792 ix = 0;
03793 iy = ry * 64;
03794
03795 do {
03796 h = (ix + 32) >> 6;
03797 i = (iy + 32) >> 6;
03798 j = (h * rx) / ry;
03799 k = (i * rx) / ry;
03800
03801 if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
03802 xmj = x - j;
03803 xpj = x + j;
03804 if (i > 0) {
03805 ypi = y + i;
03806 ymi = y - i;
03807 result |= fastPixelColorNolock(dst, xmj, ypi, color);
03808 result |= fastPixelColorNolock(dst, xpj, ypi, color);
03809 result |= fastPixelColorNolock(dst, xmj, ymi, color);
03810 result |= fastPixelColorNolock(dst, xpj, ymi, color);
03811 } else {
03812 result |= fastPixelColorNolock(dst, xmj, y, color);
03813 result |= fastPixelColorNolock(dst, xpj, y, color);
03814 }
03815 oi = i;
03816 xmk = x - k;
03817 xpk = x + k;
03818 if (h > 0) {
03819 yph = y + h;
03820 ymh = y - h;
03821 result |= fastPixelColorNolock(dst, xmk, yph, color);
03822 result |= fastPixelColorNolock(dst, xpk, yph, color);
03823 result |= fastPixelColorNolock(dst, xmk, ymh, color);
03824 result |= fastPixelColorNolock(dst, xpk, ymh, color);
03825 } else {
03826 result |= fastPixelColorNolock(dst, xmk, y, color);
03827 result |= fastPixelColorNolock(dst, xpk, y, color);
03828 }
03829 oh = h;
03830 }
03831
03832 ix = ix + iy / ry;
03833 iy = iy - ix / ry;
03834
03835 } while (i > h);
03836 }
03837
03838 } else {
03839
03840 if (rx > ry) {
03841 ix = 0;
03842 iy = rx * 64;
03843
03844 do {
03845 h = (ix + 32) >> 6;
03846 i = (iy + 32) >> 6;
03847 j = (h * ry) / rx;
03848 k = (i * ry) / rx;
03849
03850 if (((ok != k) && (oj != k)) || ((oj != j) && (ok != j)) || (k != j)) {
03851 xph = x + h;
03852 xmh = x - h;
03853 if (k > 0) {
03854 ypk = y + k;
03855 ymk = y - k;
03856 result |= pixelColorNolock (dst, xmh, ypk, color);
03857 result |= pixelColorNolock (dst, xph, ypk, color);
03858 result |= pixelColorNolock (dst, xmh, ymk, color);
03859 result |= pixelColorNolock (dst, xph, ymk, color);
03860 } else {
03861 result |= pixelColorNolock (dst, xmh, y, color);
03862 result |= pixelColorNolock (dst, xph, y, color);
03863 }
03864 ok = k;
03865 xpi = x + i;
03866 xmi = x - i;
03867 if (j > 0) {
03868 ypj = y + j;
03869 ymj = y - j;
03870 result |= pixelColorNolock (dst, xmi, ypj, color);
03871 result |= pixelColorNolock (dst, xpi, ypj, color);
03872 result |= pixelColorNolock (dst, xmi, ymj, color);
03873 result |= pixelColor(dst, xpi, ymj, color);
03874 } else {
03875 result |= pixelColorNolock (dst, xmi, y, color);
03876 result |= pixelColorNolock (dst, xpi, y, color);
03877 }
03878 oj = j;
03879 }
03880
03881 ix = ix + iy / rx;
03882 iy = iy - ix / rx;
03883
03884 } while (i > h);
03885 } else {
03886 ix = 0;
03887 iy = ry * 64;
03888
03889 do {
03890 h = (ix + 32) >> 6;
03891 i = (iy + 32) >> 6;
03892 j = (h * rx) / ry;
03893 k = (i * rx) / ry;
03894
03895 if (((oi != i) && (oh != i)) || ((oh != h) && (oi != h) && (i != h))) {
03896 xmj = x - j;
03897 xpj = x + j;
03898 if (i > 0) {
03899 ypi = y + i;
03900 ymi = y - i;
03901 result |= pixelColorNolock (dst, xmj, ypi, color);
03902 result |= pixelColorNolock (dst, xpj, ypi, color);
03903 result |= pixelColorNolock (dst, xmj, ymi, color);
03904 result |= pixelColorNolock (dst, xpj, ymi, color);
03905 } else {
03906 result |= pixelColorNolock (dst, xmj, y, color);
03907 result |= pixelColorNolock (dst, xpj, y, color);
03908 }
03909 oi = i;
03910 xmk = x - k;
03911 xpk = x + k;
03912 if (h > 0) {
03913 yph = y + h;
03914 ymh = y - h;
03915 result |= pixelColorNolock (dst, xmk, yph, color);
03916 result |= pixelColorNolock (dst, xpk, yph, color);
03917 result |= pixelColorNolock (dst, xmk, ymh, color);
03918 result |= pixelColorNolock (dst, xpk, ymh, color);
03919 } else {
03920 result |= pixelColorNolock (dst, xmk, y, color);
03921 result |= pixelColorNolock (dst, xpk, y, color);
03922 }
03923 oh = h;
03924 }
03925
03926 ix = ix + iy / ry;
03927 iy = iy - ix / ry;
03928
03929 } while (i > h);
03930 }
03931
03932 }
03933
03934
03935 if (SDL_MUSTLOCK(dst)) {
03936 SDL_UnlockSurface(dst);
03937 }
03938
03939 return (result);
03940 }
03941
03957 int ellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
03958 {
03959
03960
03961
03962 return (ellipseColor(dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
03963 }
03964
03965
03966
03967
03968
03969
03970 #if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW_H) && !defined(__SYMBIAN32__)
03971 #ifdef _M_X64
03972 #include <emmintrin.h>
03973 static __inline long
03974 lrint(float f)
03975 {
03976 return _mm_cvtss_si32(_mm_load_ss(&f));
03977 }
03978 #else
03979 __inline long int
03980 lrint (double flt)
03981 {
03982 int intgr;
03983 _asm
03984 {
03985 fld flt
03986 fistp intgr
03987 };
03988 return intgr;
03989 }
03990 #endif
03991 #endif
03992
04008 int aaellipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
04009 {
04010 Sint16 left, right, top, bottom;
04011 Sint16 x1,y1,x2,y2;
04012 int i;
04013 int a2, b2, ds, dt, dxt, t, s, d;
04014 Sint16 xp, yp, xs, ys, dyt, od, xx, yy, xc2, yc2;
04015 float cp;
04016 double sab;
04017 Uint8 weight, iweight;
04018 int result;
04019
04020
04021
04022
04023 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04024 return(0);
04025 }
04026
04027
04028
04029
04030 if ((rx < 0) || (ry < 0)) {
04031 return (-1);
04032 }
04033
04034
04035
04036
04037 if (rx == 0) {
04038 return (vlineColor(dst, x, y - ry, y + ry, color));
04039 }
04040
04041
04042
04043 if (ry == 0) {
04044 return (hlineColor(dst, x - rx, x + rx, y, color));
04045 }
04046
04047
04048
04049
04050
04051 x2 = x + rx;
04052 left = dst->clip_rect.x;
04053 if (x2<left) {
04054 return(0);
04055 }
04056 x1 = x - rx;
04057 right = dst->clip_rect.x + dst->clip_rect.w - 1;
04058 if (x1>right) {
04059 return(0);
04060 }
04061 y2 = y + ry;
04062 top = dst->clip_rect.y;
04063 if (y2<top) {
04064 return(0);
04065 }
04066 y1 = y - ry;
04067 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
04068 if (y1>bottom) {
04069 return(0);
04070 }
04071
04072
04073 a2 = rx * rx;
04074 b2 = ry * ry;
04075
04076 ds = 2 * a2;
04077 dt = 2 * b2;
04078
04079 xc2 = 2 * x;
04080 yc2 = 2 * y;
04081
04082 sab = sqrt(a2 + b2);
04083 od = (Sint16)lrint(sab*0.01) + 1;
04084 dxt = (Sint16)lrint((double)a2 / sab) + od;
04085
04086 t = 0;
04087 s = -2 * a2 * ry;
04088 d = 0;
04089
04090 xp = x;
04091 yp = y - ry;
04092
04093
04094 if (SDL_MUSTLOCK(dst)) {
04095 if (SDL_LockSurface(dst) < 0) {
04096 return (-1);
04097 }
04098 }
04099
04100
04101 result = 0;
04102
04103
04104 result |= pixelColorNolock(dst, xp, yp, color);
04105 result |= pixelColorNolock(dst, xc2 - xp, yp, color);
04106 result |= pixelColorNolock(dst, xp, yc2 - yp, color);
04107 result |= pixelColorNolock(dst, xc2 - xp, yc2 - yp, color);
04108
04109 for (i = 1; i <= dxt; i++) {
04110 xp--;
04111 d += t - b2;
04112
04113 if (d >= 0)
04114 ys = yp - 1;
04115 else if ((d - s - a2) > 0) {
04116 if ((2 * d - s - a2) >= 0)
04117 ys = yp + 1;
04118 else {
04119 ys = yp;
04120 yp++;
04121 d -= s + a2;
04122 s += ds;
04123 }
04124 } else {
04125 yp++;
04126 ys = yp + 1;
04127 d -= s + a2;
04128 s += ds;
04129 }
04130
04131 t -= dt;
04132
04133
04134 if (s != 0.0) {
04135 cp = (float) abs(d) / (float) abs(s);
04136 if (cp > 1.0) {
04137 cp = 1.0;
04138 }
04139 } else {
04140 cp = 1.0;
04141 }
04142
04143
04144 weight = (Uint8) (cp * 255);
04145 iweight = 255 - weight;
04146
04147
04148 xx = xc2 - xp;
04149 result |= pixelColorWeightNolock(dst, xp, yp, color, iweight);
04150 result |= pixelColorWeightNolock(dst, xx, yp, color, iweight);
04151
04152 result |= pixelColorWeightNolock(dst, xp, ys, color, weight);
04153 result |= pixelColorWeightNolock(dst, xx, ys, color, weight);
04154
04155
04156 yy = yc2 - yp;
04157 result |= pixelColorWeightNolock(dst, xp, yy, color, iweight);
04158 result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
04159
04160 yy = yc2 - ys;
04161 result |= pixelColorWeightNolock(dst, xp, yy, color, weight);
04162 result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
04163 }
04164
04165
04166 dyt = (Sint16)lrint((double)b2 / sab ) + od;
04167
04168 for (i = 1; i <= dyt; i++) {
04169 yp++;
04170 d -= s + a2;
04171
04172 if (d <= 0)
04173 xs = xp + 1;
04174 else if ((d + t - b2) < 0) {
04175 if ((2 * d + t - b2) <= 0)
04176 xs = xp - 1;
04177 else {
04178 xs = xp;
04179 xp--;
04180 d += t - b2;
04181 t -= dt;
04182 }
04183 } else {
04184 xp--;
04185 xs = xp - 1;
04186 d += t - b2;
04187 t -= dt;
04188 }
04189
04190 s += ds;
04191
04192
04193 if (t != 0.0) {
04194 cp = (float) abs(d) / (float) abs(t);
04195 if (cp > 1.0) {
04196 cp = 1.0;
04197 }
04198 } else {
04199 cp = 1.0;
04200 }
04201
04202
04203 weight = (Uint8) (cp * 255);
04204 iweight = 255 - weight;
04205
04206
04207 xx = xc2 - xp;
04208 yy = yc2 - yp;
04209 result |= pixelColorWeightNolock(dst, xp, yp, color, iweight);
04210 result |= pixelColorWeightNolock(dst, xx, yp, color, iweight);
04211
04212 result |= pixelColorWeightNolock(dst, xp, yy, color, iweight);
04213 result |= pixelColorWeightNolock(dst, xx, yy, color, iweight);
04214
04215
04216 xx = xc2 - xs;
04217 result |= pixelColorWeightNolock(dst, xs, yp, color, weight);
04218 result |= pixelColorWeightNolock(dst, xx, yp, color, weight);
04219
04220 result |= pixelColorWeightNolock(dst, xs, yy, color, weight);
04221 result |= pixelColorWeightNolock(dst, xx, yy, color, weight);
04222
04223 }
04224
04225
04226 if (SDL_MUSTLOCK(dst)) {
04227 SDL_UnlockSurface(dst);
04228 }
04229
04230 return (result);
04231 }
04232
04248 int aaellipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04249 {
04250
04251
04252
04253 return (aaellipseColor
04254 (dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
04255 }
04256
04257
04258
04259
04260
04261
04262
04278 int filledEllipseColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color)
04279 {
04280 Sint16 left, right, top, bottom;
04281 int result;
04282 Sint16 x1, y1, x2, y2;
04283 int ix, iy;
04284 int h, i, j, k;
04285 int oh, oi, oj, ok;
04286 int xmh, xph;
04287 int xmi, xpi;
04288 int xmj, xpj;
04289 int xmk, xpk;
04290
04291
04292
04293
04294 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04295 return(0);
04296 }
04297
04298
04299
04300
04301 if ((rx < 0) || (ry < 0)) {
04302 return (-1);
04303 }
04304
04305
04306
04307
04308 if (rx == 0) {
04309 return (vlineColor(dst, x, y - ry, y + ry, color));
04310 }
04311
04312
04313
04314 if (ry == 0) {
04315 return (hlineColor(dst, x - rx, x + rx, y, color));
04316 }
04317
04318
04319
04320
04321
04322 x2 = x + rx;
04323 left = dst->clip_rect.x;
04324 if (x2<left) {
04325 return(0);
04326 }
04327 x1 = x - rx;
04328 right = dst->clip_rect.x + dst->clip_rect.w - 1;
04329 if (x1>right) {
04330 return(0);
04331 }
04332 y2 = y + ry;
04333 top = dst->clip_rect.y;
04334 if (y2<top) {
04335 return(0);
04336 }
04337 y1 = y - ry;
04338 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
04339 if (y1>bottom) {
04340 return(0);
04341 }
04342
04343
04344
04345
04346 oh = oi = oj = ok = 0xFFFF;
04347
04348
04349
04350
04351 result = 0;
04352 if (rx > ry) {
04353 ix = 0;
04354 iy = rx * 64;
04355
04356 do {
04357 h = (ix + 32) >> 6;
04358 i = (iy + 32) >> 6;
04359 j = (h * ry) / rx;
04360 k = (i * ry) / rx;
04361
04362 if ((ok != k) && (oj != k)) {
04363 xph = x + h;
04364 xmh = x - h;
04365 if (k > 0) {
04366 result |= hlineColor(dst, xmh, xph, y + k, color);
04367 result |= hlineColor(dst, xmh, xph, y - k, color);
04368 } else {
04369 result |= hlineColor(dst, xmh, xph, y, color);
04370 }
04371 ok = k;
04372 }
04373 if ((oj != j) && (ok != j) && (k != j)) {
04374 xmi = x - i;
04375 xpi = x + i;
04376 if (j > 0) {
04377 result |= hlineColor(dst, xmi, xpi, y + j, color);
04378 result |= hlineColor(dst, xmi, xpi, y - j, color);
04379 } else {
04380 result |= hlineColor(dst, xmi, xpi, y, color);
04381 }
04382 oj = j;
04383 }
04384
04385 ix = ix + iy / rx;
04386 iy = iy - ix / rx;
04387
04388 } while (i > h);
04389 } else {
04390 ix = 0;
04391 iy = ry * 64;
04392
04393 do {
04394 h = (ix + 32) >> 6;
04395 i = (iy + 32) >> 6;
04396 j = (h * rx) / ry;
04397 k = (i * rx) / ry;
04398
04399 if ((oi != i) && (oh != i)) {
04400 xmj = x - j;
04401 xpj = x + j;
04402 if (i > 0) {
04403 result |= hlineColor(dst, xmj, xpj, y + i, color);
04404 result |= hlineColor(dst, xmj, xpj, y - i, color);
04405 } else {
04406 result |= hlineColor(dst, xmj, xpj, y, color);
04407 }
04408 oi = i;
04409 }
04410 if ((oh != h) && (oi != h) && (i != h)) {
04411 xmk = x - k;
04412 xpk = x + k;
04413 if (h > 0) {
04414 result |= hlineColor(dst, xmk, xpk, y + h, color);
04415 result |= hlineColor(dst, xmk, xpk, y - h, color);
04416 } else {
04417 result |= hlineColor(dst, xmk, xpk, y, color);
04418 }
04419 oh = h;
04420 }
04421
04422 ix = ix + iy / ry;
04423 iy = iy - ix / ry;
04424
04425 } while (i > h);
04426 }
04427
04428 return (result);
04429 }
04430
04446 int filledEllipseRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04447 {
04448
04449
04450
04451 return (filledEllipseColor
04452 (dst, x, y, rx, ry, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
04453 }
04454
04455
04456
04473 int _pieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color, Uint8 filled)
04474 {
04475 Sint16 left, right, top, bottom;
04476 Sint16 x1, y1, x2, y2;
04477 int result;
04478 double angle, start_angle, end_angle;
04479 double deltaAngle;
04480 double dr;
04481 int numpoints, i;
04482 Sint16 *vx, *vy;
04483
04484
04485
04486
04487 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04488 return(0);
04489 }
04490
04491
04492
04493
04494 if (rad < 0) {
04495 return (-1);
04496 }
04497
04498
04499
04500
04501 start = start % 360;
04502 end = end % 360;
04503
04504
04505
04506
04507 if (rad == 0) {
04508 return (pixelColor(dst, x, y, color));
04509 }
04510
04511
04512
04513
04514
04515
04516 x2 = x + rad;
04517 left = dst->clip_rect.x;
04518 if (x2<left) {
04519 return(0);
04520 }
04521 x1 = x - rad;
04522 right = dst->clip_rect.x + dst->clip_rect.w - 1;
04523 if (x1>right) {
04524 return(0);
04525 }
04526 y2 = y + rad;
04527 top = dst->clip_rect.y;
04528 if (y2<top) {
04529 return(0);
04530 }
04531 y1 = y - rad;
04532 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
04533 if (y1>bottom) {
04534 return(0);
04535 }
04536
04537
04538
04539
04540 dr = (double) rad;
04541 deltaAngle = 3.0 / dr;
04542 start_angle = (double) start *(2.0 * M_PI / 360.0);
04543 end_angle = (double) end *(2.0 * M_PI / 360.0);
04544 if (start > end) {
04545 end_angle += (2.0 * M_PI);
04546 }
04547
04548
04549 numpoints = 2;
04550
04551
04552 angle = start_angle;
04553 while (angle < end_angle) {
04554 angle += deltaAngle;
04555 numpoints++;
04556 }
04557
04558
04559 vx = vy = (Sint16 *) malloc(2 * sizeof(Uint16) * numpoints);
04560 if (vx == NULL) {
04561 return (-1);
04562 }
04563
04564
04565 vy += numpoints;
04566
04567
04568 vx[0] = x;
04569 vy[0] = y;
04570
04571
04572 angle = start_angle;
04573 vx[1] = x + (int) (dr * cos(angle));
04574 vy[1] = y + (int) (dr * sin(angle));
04575
04576 if (numpoints<3)
04577 {
04578 result = lineColor(dst, vx[0], vy[0], vx[1], vy[1], color);
04579 }
04580 else
04581 {
04582
04583 i = 2;
04584 angle = start_angle;
04585 while (angle < end_angle) {
04586 angle += deltaAngle;
04587 if (angle>end_angle)
04588 {
04589 angle = end_angle;
04590 }
04591 vx[i] = x + (int) (dr * cos(angle));
04592 vy[i] = y + (int) (dr * sin(angle));
04593 i++;
04594 }
04595
04596
04597 if (filled) {
04598 result = filledPolygonColor(dst, vx, vy, numpoints, color);
04599 } else {
04600 result = polygonColor(dst, vx, vy, numpoints, color);
04601 }
04602 }
04603
04604
04605 free(vx);
04606
04607 return (result);
04608 }
04609
04623 int pieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
04624 Sint16 start, Sint16 end, Uint32 color)
04625 {
04626 return (_pieColor(dst, x, y, rad, start, end, color, 0));
04627
04628 }
04629
04646 int pieRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
04647 Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04648 {
04649 return (_pieColor(dst, x, y, rad, start, end,
04650 ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 0));
04651
04652 }
04653
04667 int filledPieColor(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color)
04668 {
04669 return (_pieColor(dst, x, y, rad, start, end, color, 1));
04670 }
04671
04688 int filledPieRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, Sint16 rad,
04689 Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04690 {
04691 return (_pieColor(dst, x, y, rad, start, end,
04692 ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, 1));
04693 }
04694
04695
04696
04713 int trigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
04714 {
04715 Sint16 vx[3];
04716 Sint16 vy[3];
04717
04718 vx[0]=x1;
04719 vx[1]=x2;
04720 vx[2]=x3;
04721 vy[0]=y1;
04722 vy[1]=y2;
04723 vy[2]=y3;
04724
04725 return(polygonColor(dst,vx,vy,3,color));
04726 }
04727
04745 int trigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
04746 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04747 {
04748 Sint16 vx[3];
04749 Sint16 vy[3];
04750
04751 vx[0]=x1;
04752 vx[1]=x2;
04753 vx[2]=x3;
04754 vy[0]=y1;
04755 vy[1]=y2;
04756 vy[2]=y3;
04757
04758 return(polygonRGBA(dst,vx,vy,3,r,g,b,a));
04759 }
04760
04761
04762
04779 int aatrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
04780 {
04781 Sint16 vx[3];
04782 Sint16 vy[3];
04783
04784 vx[0]=x1;
04785 vx[1]=x2;
04786 vx[2]=x3;
04787 vy[0]=y1;
04788 vy[1]=y2;
04789 vy[2]=y3;
04790
04791 return(aapolygonColor(dst,vx,vy,3,color));
04792 }
04793
04811 int aatrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
04812 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04813 {
04814 Sint16 vx[3];
04815 Sint16 vy[3];
04816
04817 vx[0]=x1;
04818 vx[1]=x2;
04819 vx[2]=x3;
04820 vy[0]=y1;
04821 vy[1]=y2;
04822 vy[2]=y3;
04823
04824 return(aapolygonRGBA(dst,vx,vy,3,r,g,b,a));
04825 }
04826
04827
04828
04845 int filledTrigonColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color)
04846 {
04847 Sint16 vx[3];
04848 Sint16 vy[3];
04849
04850 vx[0]=x1;
04851 vx[1]=x2;
04852 vx[2]=x3;
04853 vy[0]=y1;
04854 vy[1]=y2;
04855 vy[2]=y3;
04856
04857 return(filledPolygonColor(dst,vx,vy,3,color));
04858 }
04859
04879 int filledTrigonRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
04880 Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04881 {
04882 Sint16 vx[3];
04883 Sint16 vy[3];
04884
04885 vx[0]=x1;
04886 vx[1]=x2;
04887 vx[2]=x3;
04888 vy[0]=y1;
04889 vy[1]=y2;
04890 vy[2]=y3;
04891
04892 return(filledPolygonRGBA(dst,vx,vy,3,r,g,b,a));
04893 }
04894
04895
04896
04908 int polygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
04909 {
04910 int result;
04911 int i;
04912 const Sint16 *x1, *y1, *x2, *y2;
04913
04914
04915
04916
04917 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
04918 return(0);
04919 }
04920
04921
04922
04923
04924 if (vx == NULL) {
04925 return (-1);
04926 }
04927 if (vy == NULL) {
04928 return (-1);
04929 }
04930
04931
04932
04933
04934 if (n < 3) {
04935 return (-1);
04936 }
04937
04938
04939
04940
04941 x1 = x2 = vx;
04942 y1 = y2 = vy;
04943 x2++;
04944 y2++;
04945
04946
04947
04948
04949 result = 0;
04950 for (i = 1; i < n; i++) {
04951 result |= lineColor(dst, *x1, *y1, *x2, *y2, color);
04952 x1 = x2;
04953 y1 = y2;
04954 x2++;
04955 y2++;
04956 }
04957 result |= lineColor(dst, *x1, *y1, *vx, *vy, color);
04958
04959 return (result);
04960 }
04961
04976 int polygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
04977 {
04978
04979
04980
04981 return (polygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
04982 }
04983
04984
04985
04997 int aapolygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
04998 {
04999 int result;
05000 int i;
05001 const Sint16 *x1, *y1, *x2, *y2;
05002
05003
05004
05005
05006 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05007 return(0);
05008 }
05009
05010
05011
05012
05013 if (vx == NULL) {
05014 return (-1);
05015 }
05016 if (vy == NULL) {
05017 return (-1);
05018 }
05019
05020
05021
05022
05023 if (n < 3) {
05024 return (-1);
05025 }
05026
05027
05028
05029
05030 x1 = x2 = vx;
05031 y1 = y2 = vy;
05032 x2++;
05033 y2++;
05034
05035
05036
05037
05038 result = 0;
05039 for (i = 1; i < n; i++) {
05040 result |= _aalineColor(dst, *x1, *y1, *x2, *y2, color, 0);
05041 x1 = x2;
05042 y1 = y2;
05043 x2++;
05044 y2++;
05045 }
05046 result |= _aalineColor(dst, *x1, *y1, *vx, *vy, color, 0);
05047
05048 return (result);
05049 }
05050
05065 int aapolygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
05066 {
05067
05068
05069
05070 return (aapolygonColor(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
05071 }
05072
05073
05074
05083 int _gfxPrimitivesCompareInt(const void *a, const void *b)
05084 {
05085 return (*(const int *) a) - (*(const int *) b);
05086 }
05087
05093 static int *gfxPrimitivesPolyIntsGlobal = NULL;
05094
05100 static int gfxPrimitivesPolyAllocatedGlobal = 0;
05101
05117 int filledPolygonColorMT(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color, int **polyInts, int *polyAllocated)
05118 {
05119 int result;
05120 int i;
05121 int y, xa, xb;
05122 int miny, maxy;
05123 int x1, y1;
05124 int x2, y2;
05125 int ind1, ind2;
05126 int ints;
05127 int *gfxPrimitivesPolyInts = NULL;
05128 int gfxPrimitivesPolyAllocated = 0;
05129
05130
05131
05132
05133 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05134 return(0);
05135 }
05136
05137
05138
05139
05140 if (vx == NULL) {
05141 return (-1);
05142 }
05143 if (vy == NULL) {
05144 return (-1);
05145 }
05146
05147
05148
05149
05150 if (n < 3) {
05151 return -1;
05152 }
05153
05154
05155
05156
05157 if ((polyInts==NULL) || (polyAllocated==NULL)) {
05158
05159 gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal;
05160 gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal;
05161 } else {
05162
05163 gfxPrimitivesPolyInts = *polyInts;
05164 gfxPrimitivesPolyAllocated = *polyAllocated;
05165 }
05166
05167
05168
05169
05170 if (!gfxPrimitivesPolyAllocated) {
05171 gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
05172 gfxPrimitivesPolyAllocated = n;
05173 } else {
05174 if (gfxPrimitivesPolyAllocated < n) {
05175 gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
05176 gfxPrimitivesPolyAllocated = n;
05177 }
05178 }
05179
05180
05181
05182
05183 if (gfxPrimitivesPolyInts==NULL) {
05184 gfxPrimitivesPolyAllocated = 0;
05185 }
05186
05187
05188
05189
05190 if ((polyInts==NULL) || (polyAllocated==NULL)) {
05191 gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts;
05192 gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated;
05193 } else {
05194 *polyInts = gfxPrimitivesPolyInts;
05195 *polyAllocated = gfxPrimitivesPolyAllocated;
05196 }
05197
05198
05199
05200
05201 if (gfxPrimitivesPolyInts==NULL) {
05202 return(-1);
05203 }
05204
05205
05206
05207
05208 miny = vy[0];
05209 maxy = vy[0];
05210 for (i = 1; (i < n); i++) {
05211 if (vy[i] < miny) {
05212 miny = vy[i];
05213 } else if (vy[i] > maxy) {
05214 maxy = vy[i];
05215 }
05216 }
05217
05218
05219
05220
05221 result = 0;
05222 for (y = miny; (y <= maxy); y++) {
05223 ints = 0;
05224 for (i = 0; (i < n); i++) {
05225 if (!i) {
05226 ind1 = n - 1;
05227 ind2 = 0;
05228 } else {
05229 ind1 = i - 1;
05230 ind2 = i;
05231 }
05232 y1 = vy[ind1];
05233 y2 = vy[ind2];
05234 if (y1 < y2) {
05235 x1 = vx[ind1];
05236 x2 = vx[ind2];
05237 } else if (y1 > y2) {
05238 y2 = vy[ind1];
05239 y1 = vy[ind2];
05240 x2 = vx[ind1];
05241 x1 = vx[ind2];
05242 } else {
05243 continue;
05244 }
05245 if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
05246 gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
05247 }
05248 }
05249
05250 qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt);
05251
05252 for (i = 0; (i < ints); i += 2) {
05253 xa = gfxPrimitivesPolyInts[i] + 1;
05254 xa = (xa >> 16) + ((xa & 32768) >> 15);
05255 xb = gfxPrimitivesPolyInts[i+1] - 1;
05256 xb = (xb >> 16) + ((xb & 32768) >> 15);
05257 result |= hlineColor(dst, xa, xb, y, color);
05258 }
05259 }
05260
05261 return (result);
05262 }
05263
05282 int filledPolygonRGBAMT(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a, int **polyInts, int *polyAllocated)
05283 {
05284
05285
05286
05287 return (filledPolygonColorMT(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, polyInts, polyAllocated));
05288 }
05289
05304 int filledPolygonColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color)
05305 {
05306
05307
05308
05309 return (filledPolygonColorMT(dst, vx, vy, n, color, NULL, NULL));
05310 }
05311
05326 int filledPolygonRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
05327 {
05328
05329
05330
05331 return (filledPolygonColorMT(dst, vx, vy, n, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a, NULL, NULL));
05332 }
05333
05347 int _HLineTextured(SDL_Surface * dst, Sint16 x1, Sint16 x2, Sint16 y, SDL_Surface *texture, int texture_dx, int texture_dy)
05348 {
05349 Sint16 left, right, top, bottom;
05350 Sint16 w;
05351 Sint16 xtmp;
05352 int result = 0;
05353 int texture_x_walker;
05354 int texture_y_start;
05355 SDL_Rect source_rect,dst_rect;
05356 int pixels_written,write_width;
05357
05358
05359
05360
05361 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05362 return(0);
05363 }
05364
05365
05366
05367
05368 if (x1 > x2) {
05369 xtmp = x1;
05370 x1 = x2;
05371 x2 = xtmp;
05372 }
05373
05374
05375
05376
05377
05378 left = dst->clip_rect.x;
05379 if (x2<left) {
05380 return(0);
05381 }
05382 right = dst->clip_rect.x + dst->clip_rect.w - 1;
05383 if (x1>right) {
05384 return(0);
05385 }
05386 top = dst->clip_rect.y;
05387 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
05388 if ((y<top) || (y>bottom)) {
05389 return (0);
05390 }
05391
05392
05393
05394
05395 if (x1 < left) {
05396 x1 = left;
05397 }
05398 if (x2 > right) {
05399 x2 = right;
05400 }
05401
05402
05403
05404
05405 w = x2 - x1 + 1;
05406
05407
05408
05409
05410 texture_x_walker = (x1 - texture_dx) % texture->w;
05411 if (texture_x_walker < 0){
05412 texture_x_walker = texture->w + texture_x_walker ;
05413 }
05414
05415 texture_y_start = (y + texture_dy) % texture->h;
05416 if (texture_y_start < 0){
05417 texture_y_start = texture->h + texture_y_start;
05418 }
05419
05420
05421 source_rect.y = texture_y_start;
05422 source_rect.x = texture_x_walker;
05423 source_rect.h = 1;
05424
05425
05426 dst_rect.y = y;
05427
05428
05429
05430 if (w <= texture->w -texture_x_walker){
05431 source_rect.w = w;
05432 source_rect.x = texture_x_walker;
05433 dst_rect.x= x1;
05434 result = (SDL_BlitSurface (texture, &source_rect , dst, &dst_rect) == 0);
05435 } else {
05436
05437 pixels_written = texture->w - texture_x_walker;
05438 source_rect.w = pixels_written;
05439 source_rect.x = texture_x_walker;
05440 dst_rect.x= x1;
05441 result |= (SDL_BlitSurface (texture, &source_rect , dst, &dst_rect) == 0);
05442 write_width = texture->w;
05443
05444
05445
05446 source_rect.x = 0;
05447 while (pixels_written < w){
05448 if (write_width >= w - pixels_written) {
05449 write_width = w - pixels_written;
05450 }
05451 source_rect.w = write_width;
05452 dst_rect.x = x1 + pixels_written;
05453 result |= (SDL_BlitSurface (texture,&source_rect , dst, &dst_rect) == 0);
05454 pixels_written += write_width;
05455 }
05456 }
05457
05458 return result;
05459 }
05460
05484 int texturedPolygonMT(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n,
05485 SDL_Surface * texture, int texture_dx, int texture_dy, int **polyInts, int *polyAllocated)
05486 {
05487 int result;
05488 int i;
05489 int y, xa, xb;
05490 int minx,maxx,miny, maxy;
05491 int x1, y1;
05492 int x2, y2;
05493 int ind1, ind2;
05494 int ints;
05495 int *gfxPrimitivesPolyInts = NULL;
05496 int gfxPrimitivesPolyAllocated = 0;
05497
05498
05499
05500
05501 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05502 return(0);
05503 }
05504
05505
05506
05507
05508 if (n < 3) {
05509 return -1;
05510 }
05511
05512
05513
05514
05515 if ((polyInts==NULL) || (polyAllocated==NULL)) {
05516
05517 gfxPrimitivesPolyInts = gfxPrimitivesPolyIntsGlobal;
05518 gfxPrimitivesPolyAllocated = gfxPrimitivesPolyAllocatedGlobal;
05519 } else {
05520
05521 gfxPrimitivesPolyInts = *polyInts;
05522 gfxPrimitivesPolyAllocated = *polyAllocated;
05523 }
05524
05525
05526
05527
05528 if (!gfxPrimitivesPolyAllocated) {
05529 gfxPrimitivesPolyInts = (int *) malloc(sizeof(int) * n);
05530 gfxPrimitivesPolyAllocated = n;
05531 } else {
05532 if (gfxPrimitivesPolyAllocated < n) {
05533 gfxPrimitivesPolyInts = (int *) realloc(gfxPrimitivesPolyInts, sizeof(int) * n);
05534 gfxPrimitivesPolyAllocated = n;
05535 }
05536 }
05537
05538
05539
05540
05541 if (gfxPrimitivesPolyInts==NULL) {
05542 gfxPrimitivesPolyAllocated = 0;
05543 }
05544
05545
05546
05547
05548 if ((polyInts==NULL) || (polyAllocated==NULL)) {
05549 gfxPrimitivesPolyIntsGlobal = gfxPrimitivesPolyInts;
05550 gfxPrimitivesPolyAllocatedGlobal = gfxPrimitivesPolyAllocated;
05551 } else {
05552 *polyInts = gfxPrimitivesPolyInts;
05553 *polyAllocated = gfxPrimitivesPolyAllocated;
05554 }
05555
05556
05557
05558
05559 if (gfxPrimitivesPolyInts==NULL) {
05560 return(-1);
05561 }
05562
05563
05564
05565
05566 miny = vy[0];
05567 maxy = vy[0];
05568 minx = vx[0];
05569 maxx = vx[0];
05570 for (i = 1; (i < n); i++) {
05571 if (vy[i] < miny) {
05572 miny = vy[i];
05573 } else if (vy[i] > maxy) {
05574 maxy = vy[i];
05575 }
05576 if (vx[i] < minx) {
05577 minx = vx[i];
05578 } else if (vx[i] > maxx) {
05579 maxx = vx[i];
05580 }
05581 }
05582 if (maxx <0 || minx > dst->w){
05583 return -1;
05584 }
05585 if (maxy <0 || miny > dst->h){
05586 return -1;
05587 }
05588
05589
05590
05591
05592 result = 0;
05593 for (y = miny; (y <= maxy); y++) {
05594 ints = 0;
05595 for (i = 0; (i < n); i++) {
05596 if (!i) {
05597 ind1 = n - 1;
05598 ind2 = 0;
05599 } else {
05600 ind1 = i - 1;
05601 ind2 = i;
05602 }
05603 y1 = vy[ind1];
05604 y2 = vy[ind2];
05605 if (y1 < y2) {
05606 x1 = vx[ind1];
05607 x2 = vx[ind2];
05608 } else if (y1 > y2) {
05609 y2 = vy[ind1];
05610 y1 = vy[ind2];
05611 x2 = vx[ind1];
05612 x1 = vx[ind2];
05613 } else {
05614 continue;
05615 }
05616 if ( ((y >= y1) && (y < y2)) || ((y == maxy) && (y > y1) && (y <= y2)) ) {
05617 gfxPrimitivesPolyInts[ints++] = ((65536 * (y - y1)) / (y2 - y1)) * (x2 - x1) + (65536 * x1);
05618 }
05619 }
05620
05621 qsort(gfxPrimitivesPolyInts, ints, sizeof(int), _gfxPrimitivesCompareInt);
05622
05623 for (i = 0; (i < ints); i += 2) {
05624 xa = gfxPrimitivesPolyInts[i] + 1;
05625 xa = (xa >> 16) + ((xa & 32768) >> 15);
05626 xb = gfxPrimitivesPolyInts[i+1] - 1;
05627 xb = (xb >> 16) + ((xb & 32768) >> 15);
05628 result |= _HLineTextured(dst, xa, xb, y, texture, texture_dx, texture_dy);
05629 }
05630 }
05631
05632 return (result);
05633 }
05634
05651 int texturedPolygon(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, SDL_Surface *texture, int texture_dx, int texture_dy)
05652 {
05653
05654
05655
05656 return (texturedPolygonMT(dst, vx, vy, n, texture, texture_dx, texture_dy, NULL, NULL));
05657 }
05658
05659
05660
05661
05665 static SDL_Surface *gfxPrimitivesFont[256];
05666
05670 static Uint32 gfxPrimitivesFontColor[256];
05671
05675 static const unsigned char *currentFontdata = gfxPrimitivesFontdata;
05676
05680 static Uint32 charWidth = 8;
05681
05685 static Uint32 charHeight = 8;
05686
05690 static Uint32 charWidthLocal = 8;
05691
05695 static Uint32 charHeightLocal = 8;
05696
05700 static Uint32 charPitch = 1;
05701
05705 static Uint32 charRotation = 0;
05706
05710 static Uint32 charSize = 8;
05711
05725 void gfxPrimitivesSetFont(const void *fontdata, Uint32 cw, Uint32 ch)
05726 {
05727 int i;
05728
05729 if ((fontdata) && (cw) && (ch)) {
05730 currentFontdata = fontdata;
05731 charWidth = cw;
05732 charHeight = ch;
05733 } else {
05734 currentFontdata = gfxPrimitivesFontdata;
05735 charWidth = 8;
05736 charHeight = 8;
05737 }
05738
05739 charPitch = (charWidth+7)/8;
05740 charSize = charPitch * charHeight;
05741
05742
05743 if ((charRotation==1) || (charRotation==3))
05744 {
05745 charWidthLocal = charHeight;
05746 charHeightLocal = charWidth;
05747 }
05748 else
05749 {
05750 charWidthLocal = charWidth;
05751 charHeightLocal = charHeight;
05752 }
05753
05754
05755 for (i = 0; i < 256; i++) {
05756 if (gfxPrimitivesFont[i]) {
05757 SDL_FreeSurface(gfxPrimitivesFont[i]);
05758 gfxPrimitivesFont[i] = NULL;
05759 }
05760 }
05761 }
05762
05771 void gfxPrimitivesSetFontRotation(Uint32 rotation)
05772 {
05773 int i;
05774
05775 rotation = rotation & 3;
05776 if (charRotation != rotation)
05777 {
05778
05779 charRotation = rotation;
05780
05781
05782 if ((charRotation==1) || (charRotation==3))
05783 {
05784 charWidthLocal = charHeight;
05785 charHeightLocal = charWidth;
05786 }
05787 else
05788 {
05789 charWidthLocal = charWidth;
05790 charHeightLocal = charHeight;
05791 }
05792
05793
05794 for (i = 0; i < 256; i++) {
05795 if (gfxPrimitivesFont[i]) {
05796 SDL_FreeSurface(gfxPrimitivesFont[i]);
05797 gfxPrimitivesFont[i] = NULL;
05798 }
05799 }
05800 }
05801 }
05802
05818 int characterColor(SDL_Surface * dst, Sint16 x, Sint16 y, char c, Uint32 color)
05819 {
05820 Sint16 left, right, top, bottom;
05821 Sint16 x1, y1, x2, y2;
05822 SDL_Rect srect;
05823 SDL_Rect drect;
05824 int result;
05825 Uint32 ix, iy;
05826 const unsigned char *charpos;
05827 Uint8 *curpos;
05828 int forced_redraw;
05829 Uint8 patt, mask;
05830 Uint8 *linepos;
05831 Uint32 pitch;
05832 SDL_Surface *rotatedCharacter;
05833 Uint32 ci;
05834
05835
05836
05837
05838 if ((dst->clip_rect.w==0) || (dst->clip_rect.h==0)) {
05839 return(0);
05840 }
05841
05842
05843
05844
05845
05846
05847 left = dst->clip_rect.x;
05848 x2 = x + charWidthLocal;
05849 if (x2<left) {
05850 return(0);
05851 }
05852 right = dst->clip_rect.x + dst->clip_rect.w - 1;
05853 x1 = x;
05854 if (x1>right) {
05855 return(0);
05856 }
05857 top = dst->clip_rect.y;
05858 y2 = y + charHeightLocal;
05859 if (y2<top) {
05860 return(0);
05861 }
05862 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
05863 y1 = y;
05864 if (y1>bottom) {
05865 return(0);
05866 }
05867
05868
05869
05870
05871 srect.x = 0;
05872 srect.y = 0;
05873 srect.w = charWidthLocal;
05874 srect.h = charHeightLocal;
05875
05876
05877
05878
05879 drect.x = x;
05880 drect.y = y;
05881 drect.w = charWidthLocal;
05882 drect.h = charHeightLocal;
05883
05884
05885 ci = (unsigned char) c;
05886
05887
05888
05889
05890
05891 if (gfxPrimitivesFont[ci] == NULL) {
05892 gfxPrimitivesFont[ci] =
05893 SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_HWSURFACE | SDL_SRCALPHA,
05894 charWidth, charHeight, 32,
05895 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF);
05896
05897
05898
05899 if (gfxPrimitivesFont[ci] == NULL) {
05900 return (-1);
05901 }
05902
05903
05904
05905 forced_redraw = 1;
05906 } else {
05907 forced_redraw = 0;
05908 }
05909
05910
05911
05912
05913 if ((gfxPrimitivesFontColor[ci] != color) || (forced_redraw)) {
05914
05915
05916
05917 SDL_SetAlpha(gfxPrimitivesFont[ci], SDL_SRCALPHA, 255);
05918 gfxPrimitivesFontColor[ci] = color;
05919
05920
05921 if (SDL_LockSurface(gfxPrimitivesFont[ci]) != 0)
05922 return (-1);
05923
05924
05925
05926
05927 charpos = currentFontdata + ci * charSize;
05928 linepos = (Uint8 *) gfxPrimitivesFont[ci]->pixels;
05929 pitch = gfxPrimitivesFont[ci]->pitch;
05930
05931
05932
05933
05934 patt = 0;
05935 for (iy = 0; iy < charHeight; iy++) {
05936 mask = 0x00;
05937 curpos = linepos;
05938 for (ix = 0; ix < charWidth; ix++) {
05939 if (!(mask >>= 1)) {
05940 patt = *charpos++;
05941 mask = 0x80;
05942 }
05943
05944 if (patt & mask)
05945 *(Uint32 *)curpos = color;
05946 else
05947 *(Uint32 *)curpos = 0;
05948 curpos += 4;
05949 }
05950 linepos += pitch;
05951 }
05952
05953
05954 SDL_UnlockSurface(gfxPrimitivesFont[ci]);
05955
05956
05957 if (charRotation>0)
05958 {
05959 rotatedCharacter = rotateSurface90Degrees(gfxPrimitivesFont[ci], charRotation);
05960 SDL_FreeSurface(gfxPrimitivesFont[ci]);
05961 gfxPrimitivesFont[ci] = rotatedCharacter;
05962 }
05963 }
05964
05965
05966
05967
05968 result = SDL_BlitSurface(gfxPrimitivesFont[ci], &srect, dst, &drect);
05969
05970 return (result);
05971 }
05972
05987 int characterRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
05988 {
05989
05990
05991
05992 return (characterColor(dst, x, y, c, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
05993 }
05994
06009 int stringColor(SDL_Surface * dst, Sint16 x, Sint16 y, const char *s, Uint32 color)
06010 {
06011 int result = 0;
06012 Sint16 curx = x;
06013 Sint16 cury = y;
06014 const char *curchar = s;
06015
06016 while (*curchar && !result) {
06017 result |= characterColor(dst, curx, cury, *curchar, color);
06018 switch (charRotation)
06019 {
06020 case 0:
06021 curx += charWidthLocal;
06022 break;
06023 case 2:
06024 curx -= charWidthLocal;
06025 break;
06026 case 1:
06027 cury += charHeightLocal;
06028 break;
06029 case 3:
06030 cury -= charHeightLocal;
06031 break;
06032 }
06033 curchar++;
06034 }
06035
06036 return (result);
06037 }
06038
06053 int stringRGBA(SDL_Surface * dst, Sint16 x, Sint16 y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
06054 {
06055
06056
06057
06058 return (stringColor(dst, x, y, s, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
06059 }
06060
06061
06062
06072 double _evaluateBezier (double *data, int ndata, double t)
06073 {
06074 double mu, result;
06075 int n,k,kn,nn,nkn;
06076 double blend,muk,munk;
06077
06078
06079 if (t<0.0) {
06080 return(data[0]);
06081 }
06082 if (t>=(double)ndata) {
06083 return(data[ndata-1]);
06084 }
06085
06086
06087 mu=t/(double)ndata;
06088
06089
06090 n=ndata-1;
06091 result=0.0;
06092 muk = 1;
06093 munk = pow(1-mu,(double)n);
06094 for (k=0;k<=n;k++) {
06095 nn = n;
06096 kn = k;
06097 nkn = n - k;
06098 blend = muk * munk;
06099 muk *= mu;
06100 munk /= (1-mu);
06101 while (nn >= 1) {
06102 blend *= nn;
06103 nn--;
06104 if (kn > 1) {
06105 blend /= (double)kn;
06106 kn--;
06107 }
06108 if (nkn > 1) {
06109 blend /= (double)nkn;
06110 nkn--;
06111 }
06112 }
06113 result += data[k] * blend;
06114 }
06115
06116 return (result);
06117 }
06118
06131 int bezierColor(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint32 color)
06132 {
06133 int result;
06134 int i;
06135 double *x, *y, t, stepsize;
06136 Sint16 x1, y1, x2, y2;
06137
06138
06139
06140
06141 if (n < 3) {
06142 return (-1);
06143 }
06144 if (s < 2) {
06145 return (-1);
06146 }
06147
06148
06149
06150
06151 stepsize=(double)1.0/(double)s;
06152
06153
06154 if ((x=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
06155 return(-1);
06156 }
06157 if ((y=(double *)malloc(sizeof(double)*(n+1)))==NULL) {
06158 free(x);
06159 return(-1);
06160 }
06161 for (i=0; i<n; i++) {
06162 x[i]=vx[i];
06163 y[i]=vy[i];
06164 }
06165 x[n]=vx[0];
06166 y[n]=vy[0];
06167
06168
06169
06170
06171 result = 0;
06172 t=0.0;
06173 x1=(Sint16)lrint(_evaluateBezier(x,n+1,t));
06174 y1=(Sint16)lrint(_evaluateBezier(y,n+1,t));
06175 for (i = 0; i <= (n*s); i++) {
06176 t += stepsize;
06177 x2=(Sint16)_evaluateBezier(x,n,t);
06178 y2=(Sint16)_evaluateBezier(y,n,t);
06179 result |= lineColor(dst, x1, y1, x2, y2, color);
06180 x1 = x2;
06181 y1 = y2;
06182 }
06183
06184
06185 free(x);
06186 free(y);
06187
06188 return (result);
06189 }
06190
06206 int bezierRGBA(SDL_Surface * dst, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
06207 {
06208
06209
06210
06211 return (bezierColor(dst, vx, vy, n, s, ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
06212 }
06213
06214
06233 int _bresenhamInitialize(SDL_gfxBresenhamIterator *b, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2)
06234 {
06235 int temp;
06236
06237 if (b==NULL) {
06238 return(-1);
06239 }
06240
06241 b->x = x1;
06242 b->y = y1;
06243
06244
06245 if ((b->dx = x2 - x1) != 0) {
06246 if (b->dx < 0) {
06247 b->dx = -b->dx;
06248 b->s1 = -1;
06249 } else {
06250 b->s1 = 1;
06251 }
06252 } else {
06253 b->s1 = 0;
06254 }
06255
06256
06257 if ((b->dy = y2 - y1) != 0) {
06258 if (b->dy < 0) {
06259 b->dy = -b->dy;
06260 b->s2 = -1;
06261 } else {
06262 b->s2 = 1;
06263 }
06264 } else {
06265 b->s2 = 0;
06266 }
06267
06268 if (b->dy > b->dx) {
06269 temp = b->dx;
06270 b->dx = b->dy;
06271 b->dy = temp;
06272 b->swapdir = 1;
06273 } else {
06274 b->swapdir = 0;
06275 }
06276
06277 b->count = b->dx;
06278 b->dy <<= 1;
06279 b->error = b->dy - b->dx;
06280 b->dx <<= 1;
06281
06282 return(0);
06283 }
06284
06285
06295 int _bresenhamIterate(SDL_gfxBresenhamIterator *b)
06296 {
06297 if (b==NULL) {
06298 return (-1);
06299 }
06300
06301
06302 if (b->count <= 0) {
06303 return (2);
06304 }
06305
06306 while (b->error >= 0) {
06307 if (b->swapdir) {
06308 b->x += b->s1;
06309 } else {
06310 b->y += b->s2;
06311 }
06312
06313 b->error -= b->dx;
06314 }
06315
06316 if (b->swapdir) {
06317 b->y += b->s2;
06318 } else {
06319 b->x += b->s1;
06320 }
06321
06322 b->error += b->dy;
06323 b->count--;
06324
06325
06326 return ((b->count) ? 0 : 1);
06327 }
06328
06329
06338 void _murphyParaline(SDL_gfxMurphyIterator *m, Sint16 x, Sint16 y, int d1)
06339 {
06340 int p;
06341 d1 = -d1;
06342
06343
06344
06345
06346 if (SDL_MUSTLOCK(m->dst)) {
06347 SDL_LockSurface(m->dst);
06348 }
06349
06350 for (p = 0; p <= m->u; p++) {
06351
06352 pixelColorNolock(m->dst, x, y, m->color);
06353
06354 if (d1 <= m->kt) {
06355 if (m->oct2 == 0) {
06356 x++;
06357 } else {
06358 if (m->quad4 == 0) {
06359 y++;
06360 } else {
06361 y--;
06362 }
06363 }
06364 d1 += m->kv;
06365 } else {
06366 x++;
06367 if (m->quad4 == 0) {
06368 y++;
06369 } else {
06370 y--;
06371 }
06372 d1 += m->kd;
06373 }
06374 }
06375
06376
06377 if (SDL_MUSTLOCK(m->dst)) {
06378 SDL_UnlockSurface(m->dst);
06379 }
06380
06381 m->tempx = x;
06382 m->tempy = y;
06383 }
06384
06400 void _murphyIteration(SDL_gfxMurphyIterator *m, Uint8 miter,
06401 Uint16 ml1bx, Uint16 ml1by, Uint16 ml2bx, Uint16 ml2by,
06402 Uint16 ml1x, Uint16 ml1y, Uint16 ml2x, Uint16 ml2y)
06403 {
06404 int atemp1, atemp2;
06405 int ftmp1, ftmp2;
06406 Uint16 m1x, m1y, m2x, m2y;
06407 Uint16 fix, fiy, lax, lay, curx, cury;
06408 Uint16 px[4], py[4];
06409 SDL_gfxBresenhamIterator b;
06410
06411 if (miter > 1) {
06412 if (m->first1x != -32768) {
06413 fix = (m->first1x + m->first2x) / 2;
06414 fiy = (m->first1y + m->first2y) / 2;
06415 lax = (m->last1x + m->last2x) / 2;
06416 lay = (m->last1y + m->last2y) / 2;
06417 curx = (ml1x + ml2x) / 2;
06418 cury = (ml1y + ml2y) / 2;
06419
06420 atemp1 = (fix - curx);
06421 atemp2 = (fiy - cury);
06422 ftmp1 = atemp1 * atemp1 + atemp2 * atemp2;
06423 atemp1 = (lax - curx);
06424 atemp2 = (lay - cury);
06425 ftmp2 = atemp1 * atemp1 + atemp2 * atemp2;
06426
06427 if (ftmp1 <= ftmp2) {
06428 m1x = m->first1x;
06429 m1y = m->first1y;
06430 m2x = m->first2x;
06431 m2y = m->first2y;
06432 } else {
06433 m1x = m->last1x;
06434 m1y = m->last1y;
06435 m2x = m->last2x;
06436 m2y = m->last2y;
06437 }
06438
06439 atemp1 = (m2x - ml2x);
06440 atemp2 = (m2y - ml2y);
06441 ftmp1 = atemp1 * atemp1 + atemp2 * atemp2;
06442 atemp1 = (m2x - ml2bx);
06443 atemp2 = (m2y - ml2by);
06444 ftmp2 = atemp1 * atemp1 + atemp2 * atemp2;
06445
06446 if (ftmp2 >= ftmp1) {
06447 ftmp1 = ml2bx;
06448 ftmp2 = ml2by;
06449 ml2bx = ml2x;
06450 ml2by = ml2y;
06451 ml2x = ftmp1;
06452 ml2y = ftmp2;
06453 ftmp1 = ml1bx;
06454 ftmp2 = ml1by;
06455 ml1bx = ml1x;
06456 ml1by = ml1y;
06457 ml1x = ftmp1;
06458 ml1y = ftmp2;
06459 }
06460
06461
06462
06463
06464 if (SDL_MUSTLOCK(m->dst)) {
06465 SDL_LockSurface(m->dst);
06466 }
06467
06468 _bresenhamInitialize(&b, m2x, m2y, m1x, m1y);
06469 do {
06470 pixelColorNolock(m->dst, b.x, b.y, m->color);
06471 } while (_bresenhamIterate(&b)==0);
06472
06473 _bresenhamInitialize(&b, m1x, m1y, ml1bx, ml1by);
06474 do {
06475 pixelColorNolock(m->dst, b.x, b.y, m->color);
06476 } while (_bresenhamIterate(&b)==0);
06477
06478 _bresenhamInitialize(&b, ml1bx, ml1by, ml2bx, ml2by);
06479 do {
06480 pixelColorNolock(m->dst, b.x, b.y, m->color);
06481 } while (_bresenhamIterate(&b)==0);
06482
06483 _bresenhamInitialize(&b, ml2bx, ml2by, m2x, m2y);
06484 do {
06485 pixelColorNolock(m->dst, b.x, b.y, m->color);
06486 } while (_bresenhamIterate(&b)==0);
06487
06488
06489 if (SDL_MUSTLOCK(m->dst)) {
06490 SDL_UnlockSurface(m->dst);
06491 }
06492
06493 px[0] = m1x;
06494 px[1] = m2x;
06495 px[2] = ml1bx;
06496 px[3] = ml2bx;
06497 py[0] = m1y;
06498 py[1] = m2y;
06499 py[2] = ml1by;
06500 py[3] = ml2by;
06501 polygonColor(m->dst, px, py, 4, m->color);
06502 }
06503 }
06504
06505 m->last1x = ml1x;
06506 m->last1y = ml1y;
06507 m->last2x = ml2x;
06508 m->last2y = ml2y;
06509 m->first1x = ml1bx;
06510 m->first1y = ml1by;
06511 m->first2x = ml2bx;
06512 m->first2y = ml2by;
06513 }
06514
06515
06516 #define HYPOT(x,y) sqrt((double)(x)*(double)(x)+(double)(y)*(double)(y))
06517
06532 void _murphyWideline(SDL_gfxMurphyIterator *m, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 width, Uint8 miter)
06533 {
06534 float offset = width / 2.f;
06535
06536 Sint16 temp;
06537 Sint16 ptx, pty, ptxx, ptxy, ml1x, ml1y, ml2x, ml2y, ml1bx, ml1by, ml2bx, ml2by;
06538
06539 int d0, d1;
06540
06541 int q;
06542 int tmp;
06543
06544 int dd;
06545 int tk;
06546 double ang;
06547 double sang, cang;
06548
06549
06550 m->u = x2 - x1;
06551 m->v = y2 - y1;
06552
06553 if (m->u < 0) {
06554 temp = x1;
06555 x1 = x2;
06556 x2 = temp;
06557 temp = y1;
06558 y1 = y2;
06559 y1 = temp;
06560 m->u *= -1;
06561 m->v *= -1;
06562 }
06563
06564 if (m->v < 0) {
06565 m->v *= -1;
06566 m->quad4 = 1;
06567 } else {
06568 m->quad4 = 0;
06569 }
06570
06571 if (m->v > m->u) {
06572 tmp = m->u;
06573 m->u = m->v;
06574 m->v = tmp;
06575 m->oct2 = 1;
06576 } else {
06577 m->oct2 = 0;
06578 }
06579
06580 m->ku = m->u + m->u;
06581 m->kv = m->v + m->v;
06582 m->kd = m->kv - m->ku;
06583 m->kt = m->u - m->kv;
06584
06585 d0 = 0;
06586 d1 = 0;
06587 dd = 0;
06588
06589 ang = atan((double) m->v / (double) m->u);
06590 sang = sin(ang);
06591 cang = cos(ang);
06592
06593 if (m->oct2 == 0) {
06594 ptx = x1 + (Sint16)lrint(offset * sang);
06595 if (m->quad4 == 0) {
06596 pty = y1 - (Sint16)lrint(offset * cang);
06597 } else {
06598 pty = y1 + (Sint16)lrint(offset * cang);
06599 }
06600 } else {
06601 ptx = x1 - (Sint16)lrint(offset * cang);
06602 if (m->quad4 == 0) {
06603 pty = y1 + (Sint16)lrint(offset * sang);
06604 } else {
06605 pty = y1 - (Sint16)lrint(offset * sang);
06606 }
06607 }
06608
06609
06610 tk = (int) (4. * HYPOT(ptx - x1, pty - y1) * HYPOT(m->u, m->v));
06611
06612 if (miter == 0) {
06613 m->first1x = -32768;
06614 m->first1y = -32768;
06615 m->first2x = -32768;
06616 m->first2y = -32768;
06617 m->last1x = -32768;
06618 m->last1y = -32768;
06619 m->last2x = -32768;
06620 m->last2y = -32768;
06621 }
06622 ptxx = ptx;
06623 ptxy = pty;
06624
06625 for (q = 0; dd <= tk; q++) {
06626
06627 _murphyParaline(m, ptx, pty, d1);
06628 if (q == 0) {
06629 ml1x = ptx;
06630 ml1y = pty;
06631 ml1bx = m->tempx;
06632 ml1by = m->tempy;
06633 } else {
06634 ml2x = ptx;
06635 ml2y = pty;
06636 ml2bx = m->tempx;
06637 ml2by = m->tempy;
06638 }
06639 if (d0 < m->kt) {
06640 if (m->oct2 == 0) {
06641 if (m->quad4 == 0) {
06642 pty++;
06643 } else {
06644 pty--;
06645 }
06646 } else {
06647 ptx++;
06648 }
06649 } else {
06650 dd += m->kv;
06651 d0 -= m->ku;
06652 if (d1 < m->kt) {
06653 if (m->oct2 == 0) {
06654 ptx--;
06655 if (m->quad4 == 0) {
06656 pty++;
06657 } else {
06658 pty--;
06659 }
06660 } else {
06661 ptx++;
06662 if (m->quad4 == 0) {
06663 pty--;
06664 } else {
06665 pty++;
06666 }
06667 }
06668 d1 += m->kv;
06669 } else {
06670 if (m->oct2 == 0) {
06671 ptx--;
06672 } else {
06673 if (m->quad4 == 0) {
06674 pty--;
06675 } else {
06676 pty++;
06677 }
06678 }
06679 d1 += m->kd;
06680 if (dd > tk) {
06681 _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y);
06682 return;
06683 }
06684 _murphyParaline(m, ptx, pty, d1);
06685 if (m->oct2 == 0) {
06686 if (m->quad4 == 0) {
06687 pty++;
06688 } else {
06689
06690 pty--;
06691 }
06692 } else {
06693 ptx++;
06694 }
06695 }
06696 }
06697 dd += m->ku;
06698 d0 += m->kv;
06699 }
06700
06701 _murphyIteration(m, miter, ml1bx, ml1by, ml2bx, ml2by, ml1x, ml1y, ml2x, ml2y);
06702 }
06703
06704
06718 int thickLineColor(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 width, Uint32 color)
06719 {
06720 SDL_gfxMurphyIterator m;
06721
06722 if (dst == NULL) return -1;
06723 if (width < 1) return -1;
06724
06725 m.dst = dst;
06726 m.color = color;
06727
06728 _murphyWideline(&m, x1, y1, x2, y2, width, 0);
06729 _murphyWideline(&m, x1, y1, x2, y2, width, 1);
06730
06731 return(0);
06732 }
06733
06750 int thickLineRGBA(SDL_Surface * dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint8 width, Uint8 r, Uint8 g, Uint8 b, Uint8 a)
06751 {
06752 return (thickLineColor(dst, x1, y1, x2, y2, width,
06753 ((Uint32) r << 24) | ((Uint32) g << 16) | ((Uint32) b << 8) | (Uint32) a));
06754 }