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