00001 #include "OSDLFromGfx.h"
00002
00003 #include "Ceylan.h"
00004
00005 #include "SDL.h"
00006
00007
00008
00009
00010 using namespace Ceylan ;
00011 using namespace Ceylan::Log ;
00012
00013 using namespace OSDL::Video ;
00014
00015
00016 #ifdef OSDL_USES_CONFIG_H
00017 #include <OSDLConfig.h>
00018
00019 #endif // OSDL_USES_CONFIG_H
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #define clip_xmin(surface) surface->clip_rect.x
00036 #define clip_xmax(surface) surface->clip_rect.x+surface->clip_rect.w-1
00037 #define clip_ymin(surface) surface->clip_rect.y
00038 #define clip_ymax(surface) surface->clip_rect.y+surface->clip_rect.h-1
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 int filledCircleColorNotBlended( SDL_Surface * dst,
00057 Ceylan::Sint16 x, Ceylan::Sint16 y,
00058 Ceylan::Sint16 r, OSDL::Video::Pixels::ColorDefinition ) ;
00059
00060
00061
00080 int putPixelAlpha( SDL_Surface * surface, Ceylan::Sint16 x, Ceylan::Sint16 y,
00081 OSDL::Video::Pixels::PixelColor color,
00082 OSDL::Video::Pixels::ColorElement alpha )
00083 {
00084
00085
00086 #if OSDL_DEBUG_PIXEL
00087
00088 if ( x % 20 == 0 && y % 20 == 0 )
00089 {
00090 LogPlug::trace( "putPixelAlpha (OSDLFromGfx.cc) : putting at ["
00091 + Ceylan::toString( x ) + ";" + Ceylan::toString( y )
00092 + "] pixel color " + Pixels::toString(
00093 Pixels::convertPixelColorToColorDefinition(
00094 * surface->format, color ) )
00095 + " with alpha coordinate = "
00096 + Ceylan::toNumericalString( alpha ) ) ;
00097 }
00098
00099 #endif // OSDL_DEBUG_PIXEL
00100
00101 Ceylan::Uint32 Rmask = surface->format->Rmask ;
00102 Ceylan::Uint32 Gmask = surface->format->Gmask ;
00103 Ceylan::Uint32 Bmask = surface->format->Bmask ;
00104 Ceylan::Uint32 Amask = surface->format->Amask ;
00105
00106 Ceylan::Uint32 R, G, B, A = 0 ;
00107
00108
00109 if ( x >= clip_xmin(surface) && x <= clip_xmax(surface)
00110 && y >= clip_ymin(surface) && y <= clip_ymax(surface) )
00111 {
00112
00113 switch( surface->format->BytesPerPixel )
00114 {
00115
00116 case 1:
00117 {
00118
00119
00120 if (alpha == 255)
00121 {
00122 *((Ceylan::Uint8 *) surface->pixels + y * surface->pitch + x)
00123 = color ;
00124 }
00125 else
00126 {
00127 Ceylan::Uint8 *pixel =
00128 (Ceylan::Uint8 *) surface->pixels + y * surface->pitch + x ;
00129
00130 Ceylan::Uint8 dR = surface->format->palette->colors[*pixel].r;
00131 Ceylan::Uint8 dG = surface->format->palette->colors[*pixel].g;
00132 Ceylan::Uint8 dB = surface->format->palette->colors[*pixel].b;
00133 Ceylan::Uint8 sR = surface->format->palette->colors[color].r;
00134 Ceylan::Uint8 sG = surface->format->palette->colors[color].g;
00135 Ceylan::Uint8 sB = surface->format->palette->colors[color].b;
00136
00137 dR = dR + ((sR - dR) * alpha >> 8);
00138 dG = dG + ((sG - dG) * alpha >> 8);
00139 dB = dB + ((sB - dB) * alpha >> 8);
00140
00141 *pixel = SDL_MapRGB(surface->format, dR, dG, dB);
00142 }
00143 }
00144 break ;
00145
00146 case 2:
00147 {
00148
00149
00150 if (alpha == 255)
00151 {
00152
00153 *((Ceylan::Uint16 *) surface->pixels + y * surface->pitch / 2
00154 + x) = color;
00155
00156 }
00157 else
00158 {
00159
00160 Ceylan::Uint16 *pixel = (Ceylan::Uint16 *) surface->pixels
00161 + y * surface->pitch / 2 + x;
00162 Ceylan::Uint32 dc = *pixel;
00163
00164 R = ((dc & Rmask)
00165 + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00166
00167 G = ((dc & Gmask)
00168 + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00169 B = ((dc & Bmask)
00170 + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00171
00172 if (Amask)
00173 A = ((dc & Amask) + (((color & Amask) - (dc & Amask))
00174 * alpha >> 8)) & Amask;
00175
00176 *pixel = R | G | B | A;
00177
00178 }
00179 }
00180 break;
00181
00182 case 3:
00183 {
00184
00185 Ceylan::Uint8 *pix = (Ceylan::Uint8 *) surface->pixels
00186 + y * surface->pitch + x * 3;
00187 Ceylan::Uint8 rshift8 = surface->format->Rshift / 8;
00188 Ceylan::Uint8 gshift8 = surface->format->Gshift / 8;
00189 Ceylan::Uint8 bshift8 = surface->format->Bshift / 8;
00190 Ceylan::Uint8 ashift8 = surface->format->Ashift / 8;
00191
00192
00193 if (alpha == 255)
00194 {
00195 *(pix + rshift8) = color >> surface->format->Rshift;
00196 *(pix + gshift8) = color >> surface->format->Gshift;
00197 *(pix + bshift8) = color >> surface->format->Bshift;
00198 *(pix + ashift8) = color >> surface->format->Ashift;
00199 }
00200 else
00201 {
00202 Ceylan::Uint8 dR, dG, dB, dA = 0;
00203 Ceylan::Uint8 sR, sG, sB, sA = 0;
00204
00205 pix = (Ceylan::Uint8 *) surface->pixels
00206 + y * surface->pitch + x * 3;
00207
00208 dR = *((pix) + rshift8);
00209 dG = *((pix) + gshift8);
00210 dB = *((pix) + bshift8);
00211 dA = *((pix) + ashift8);
00212
00213 sR = (color >> surface->format->Rshift) & 0xff;
00214 sG = (color >> surface->format->Gshift) & 0xff;
00215 sB = (color >> surface->format->Bshift) & 0xff;
00216 sA = (color >> surface->format->Ashift) & 0xff;
00217
00218 dR = dR + ((sR - dR) * alpha >> 8);
00219 dG = dG + ((sG - dG) * alpha >> 8);
00220 dB = dB + ((sB - dB) * alpha >> 8);
00221 dA = dA + ((sA - dA) * alpha >> 8);
00222
00223 *((pix) + rshift8) = dR;
00224 *((pix) + gshift8) = dG;
00225 *((pix) + bshift8) = dB;
00226 *((pix) + ashift8) = dA;
00227 }
00228 }
00229 break;
00230
00231
00232 case 4:
00233 {
00234
00235 if (alpha == 255)
00236 {
00237 *((Ceylan::Uint32 *) surface->pixels
00238 + y * surface->pitch / 4 + x) = color;
00239 }
00240 else
00241 {
00242
00243 Ceylan::Uint32 *pixel = (Ceylan::Uint32 *) surface->pixels
00244 + y * surface->pitch / 4 + x;
00245
00246 Ceylan::Uint32 dc = *pixel;
00247
00248 R = ((dc & Rmask)
00249 + (((color & Rmask) - (dc & Rmask)) * alpha >> 8)) & Rmask;
00250
00251 G = ((dc & Gmask)
00252 + (((color & Gmask) - (dc & Gmask)) * alpha >> 8)) & Gmask;
00253
00254 B = ((dc & Bmask)
00255 + (((color & Bmask) - (dc & Bmask)) * alpha >> 8)) & Bmask;
00256
00257 if (Amask)
00258 A = ((dc & Amask) + (((color & Amask) - (dc & Amask))
00259 * alpha >> 8)) & Amask;
00260
00261 *pixel = R | G | B | A;
00262
00263 }
00264 }
00265 break;
00266
00267 default:
00268 LogPlug::error( "putPixelAlpha : unexpected bpp ("
00269 + Ceylan::toString( surface->format->BytesPerPixel ) + ")" ) ;
00270 break ;
00271
00272
00273 }
00274
00275
00276 }
00277 else
00278 {
00279
00280
00281 #if OSDL_DEBUG_PIXEL
00282 LogPlug::trace( "putPixelAlpha (OSDLFromGfx.cc) : "
00283 "pixel clipped out since location ["
00284 + Ceylan::toString( x ) + ";" + Ceylan::toString( y )
00285 + "] is out of surface bounds" ) ;
00286 #endif // OSDL_DEBUG_PIXEL
00287
00288 }
00289
00290 return 0 ;
00291
00292 }
00293
00294
00295
00296 int filledCircleRGBANotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00297 Ceylan::Sint16 y, Ceylan::Sint16 rad, Ceylan::Uint8 r, Ceylan::Uint8 g,
00298 Ceylan::Uint8 b, Ceylan::Uint8 a )
00299 {
00300
00301
00302
00303
00304 return ::filledCircleColorNotBlended( dst, x, y, rad,
00305 Pixels::convertRGBAToColorDefinition( r, g, b, a ) ) ;
00306
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319 #ifdef OSDL_CIRCLE_NOT_BLENDED_IMPLEMENTED
00320
00321 int aacircleRGBANotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00322 Ceylan::Sint16 y, Ceylan::Sint16 rad, Ceylan::Uint8 r, Ceylan::Uint8 g,
00323 Ceylan::Uint8 b, Ceylan::Uint8 a )
00324 {
00325
00326
00327
00328
00329 return ::aaellipseColorNotBlended( dst, x, y, rad, rad,
00330 Pixels::convertRGBAToColorDefinition( r, g, b, a ) ) ;
00331
00332 }
00333
00334
00335
00336 int ::circleRGBANotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00337 Ceylan::Sint16 y, Ceylan::Sint16 rad, Ceylan::Uint8 r,
00338 Ceylan::Uint8 g, Ceylan::Uint8 b, Ceylan::Uint8 a)
00339 {
00340
00341
00342
00343
00344 return ::circleColor( dst, x, y, rad,
00345 Pixels::convertRGBAToColorDefinition( r, g, b, a ) ) ;
00346
00347 }
00348
00349
00350 #endif // OSDL_CIRCLE_NOT_BLENDED_IMPLEMENTED
00351
00352
00353
00354 int filledCircleColorNotBlended( SDL_Surface * dst, Ceylan::Sint16 x,
00355 Ceylan::Sint16 y, Ceylan::Sint16 r, Pixels::ColorDefinition color )
00356 {
00357
00358 #if OSDL_DEBUG_PIXEL
00359
00360 LogPlug::trace( "filledCircleColorNotBlended : "
00361 "drawing a non-blended disc at ["
00362 + Ceylan::toString( x ) + ";" + Ceylan::toString( y )
00363 + "], with radius = " + Ceylan::toString( r )
00364 + " and color definition " + Pixels::toString( color ) ) ;
00365
00366 #endif // OSDL_DEBUG_PIXEL
00367
00368 Ceylan::Sint16 left, right, top, bottom;
00369 int result;
00370 Ceylan::Sint16 x1, y1, x2, y2;
00371 Ceylan::Sint16 cx = 0;
00372 Ceylan::Sint16 cy = r;
00373 Ceylan::Sint16 ocx = ( Ceylan::Sint16 ) 0xffff;
00374 Ceylan::Sint16 ocy = ( Ceylan::Sint16 ) 0xffff;
00375 Ceylan::Sint16 df = 1 - r;
00376 Ceylan::Sint16 d_e = 3;
00377 Ceylan::Sint16 d_se = -2 * r + 5;
00378 Ceylan::Sint16 xpcx, xmcx, xpcy, xmcy;
00379 Ceylan::Sint16 ypcy, ymcy, ypcx, ymcx;
00380
00381 Pixels::PixelColor convertedColor = SDL_MapRGBA( dst->format,
00382 color.r, color.g, color.b, color.unused ) ;
00383
00384
00385
00386
00387 if (r < 0) {
00388 return (-1);
00389 }
00390
00391
00392
00393
00394 if (r == 0) {
00395
00396
00397
00398
00399
00400
00401 fastPixelColor( dst, x, y, convertedColor ) ;
00402 }
00403
00404
00405
00406
00407 left = dst->clip_rect.x;
00408 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00409 top = dst->clip_rect.y;
00410 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00411
00412
00413
00414
00415 x1 = x - r;
00416 x2 = x + r;
00417 y1 = y - r;
00418 y2 = y + r;
00419 if ((x1<left) && (x2<left)) {
00420 return(0);
00421 }
00422 if ((x1>right) && (x2>right)) {
00423 return(0);
00424 }
00425 if ((y1<top) && (y2<top)) {
00426 return(0);
00427 }
00428 if ((y1>bottom) && (y2>bottom)) {
00429 return(0);
00430 }
00431
00432
00433
00434
00435 result = 0;
00436 do {
00437 xpcx = x + cx;
00438 xmcx = x - cx;
00439 xpcy = x + cy;
00440 xmcy = x - cy;
00441 if (ocy != cy) {
00442 if (cy > 0) {
00443 ypcy = y + cy;
00444 ymcy = y - cy;
00445
00446
00447
00448
00449
00450
00451
00452 result |= hlineColorStore(dst, xmcx, xpcx, ypcy, convertedColor);
00453 result |= hlineColorStore(dst, xmcx, xpcx, ymcy, convertedColor);
00454 } else {
00455 result |= hlineColorStore(dst, xmcx, xpcx, y, convertedColor);
00456 }
00457 ocy = cy;
00458 }
00459 if (ocx != cx) {
00460 if (cx != cy) {
00461 if (cx > 0) {
00462 ypcx = y + cx;
00463 ymcx = y - cx;
00464 result |= hlineColorStore(dst, xmcy, xpcy, ymcx, convertedColor);
00465 result |= hlineColorStore(dst, xmcy, xpcy, ypcx, convertedColor);
00466 } else {
00467 result |= hlineColorStore(dst, xmcy, xpcy, y, convertedColor);
00468 }
00469 }
00470 ocx = cx;
00471 }
00472
00473
00474
00475 if (df < 0) {
00476 df += d_e;
00477 d_e += 2;
00478 d_se += 2;
00479 } else {
00480 df += d_se;
00481 d_e += 2;
00482 d_se += 4;
00483 cy--;
00484 }
00485 cx++;
00486 } while (cx <= cy);
00487
00488 return (result);
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 int hlineColorStore( SDL_Surface * dst, Ceylan::Sint16 x1,
00505 Ceylan::Sint16 x2, Ceylan::Sint16 y, Pixels::PixelColor color )
00506 {
00507 Ceylan::Sint16 left, right, top, bottom;
00508 Ceylan::Uint8 *pixel, *pixellast;
00509 int dx;
00510 int pixx, pixy;
00511 Ceylan::Sint16 w;
00512 Ceylan::Sint16 xtmp;
00513 int result = -1;
00514
00515
00516
00517
00518 left = dst->clip_rect.x;
00519 right = dst->clip_rect.x + dst->clip_rect.w - 1;
00520 top = dst->clip_rect.y;
00521 bottom = dst->clip_rect.y + dst->clip_rect.h - 1;
00522
00523
00524
00525
00526 if ((x1<left) && (x2<left)) {
00527 return(0);
00528 }
00529 if ((x1>right) && (x2>right)) {
00530 return(0);
00531 }
00532 if ((y<top) || (y>bottom)) {
00533 return (0);
00534 }
00535
00536
00537
00538
00539 if (x1 < left) {
00540 x1 = left;
00541 }
00542 if (x2 > right) {
00543 x2 = right;
00544 }
00545
00546
00547
00548
00549 if (x1 > x2) {
00550 xtmp = x1;
00551 x1 = x2;
00552 x2 = xtmp;
00553 }
00554
00555
00556
00557
00558 w = x2 - x1;
00559
00560
00561
00562
00563 if (w < 0) {
00564 return (0);
00565 }
00566
00567
00568
00569
00570 SDL_LockSurface(dst);
00571
00572
00573
00574
00575 dx = w;
00576 pixx = dst->format->BytesPerPixel;
00577 pixy = dst->pitch;
00578 pixel = ((Ceylan::Uint8 *) dst->pixels) + pixx * (int) x1 + pixy * (int) y;
00579
00580
00581
00582
00583 switch (dst->format->BytesPerPixel) {
00584 case 1:
00585 memset(pixel, color, dx);
00586 break;
00587 case 2:
00588 pixellast = pixel + dx + dx;
00589 for (; pixel <= pixellast; pixel += pixx) {
00590 *( Ceylan::Uint16 * ) pixel = color;
00591 }
00592 break;
00593 case 3:
00594 pixellast = pixel + dx + dx + dx;
00595 for (; pixel <= pixellast; pixel += pixx) {
00596 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00597 pixel[0] = (color >> 16) & 0xff;
00598 pixel[1] = (color >> 8) & 0xff;
00599 pixel[2] = color & 0xff;
00600 } else {
00601 pixel[0] = color & 0xff;
00602 pixel[1] = (color >> 8) & 0xff;
00603 pixel[2] = (color >> 16) & 0xff;
00604 }
00605 }
00606 break;
00607 default:
00608 dx = dx + dx;
00609 pixellast = pixel + dx + dx;
00610 for (; pixel <= pixellast; pixel += pixx)
00611 {
00612 *( Ceylan::Uint32 * ) pixel = color;
00613 }
00614 break;
00615 }
00616
00617
00618
00619
00620 SDL_UnlockSurface(dst);
00621
00622
00623
00624
00625 result = 0;
00626
00627 return (result);
00628 }
00629
00630
00631
00632
00633
00634
00635
00636
00637 int fastPixelColor(SDL_Surface * dst, Ceylan::Sint16 x,
00638 Ceylan::Sint16 y, Ceylan::Uint32 color)
00639 {
00640 int result;
00641
00642
00643
00644
00645 if (SDL_MUSTLOCK(dst)) {
00646 if (SDL_LockSurface(dst) < 0) {
00647 return (-1);
00648 }
00649 }
00650
00651 result = fastPixelColorNolock(dst, x, y, color);
00652
00653
00654
00655
00656 if (SDL_MUSTLOCK(dst)) {
00657 SDL_UnlockSurface(dst);
00658 }
00659
00660 return (result);
00661 }
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 int fastPixelColorNolock(SDL_Surface * dst, Ceylan::Sint16 x,
00673 Ceylan::Sint16 y, Pixels::PixelColor color)
00674 {
00675
00676 int bpp;
00677 Ceylan::Uint8 *p;
00678
00679
00680
00681
00682 if ((x >= clip_xmin(dst)) && (x <= clip_xmax(dst)) && (y >= clip_ymin(dst))
00683 && (y <= clip_ymax(dst))) {
00684
00685
00686
00687
00688 bpp = dst->format->BytesPerPixel;
00689 p = (Ceylan::Uint8 *) dst->pixels + y * dst->pitch + x * bpp;
00690 switch (bpp) {
00691 case 1:
00692 *p = color;
00693 break;
00694 case 2:
00695 *( Ceylan::Uint16 * ) p = color;
00696 break;
00697 case 3:
00698 if (SDL_BYTEORDER == SDL_BIG_ENDIAN) {
00699 p[0] = (color >> 16) & 0xff;
00700 p[1] = (color >> 8) & 0xff;
00701 p[2] = color & 0xff;
00702 } else {
00703 p[0] = color & 0xff;
00704 p[1] = (color >> 8) & 0xff;
00705 p[2] = (color >> 16) & 0xff;
00706 }
00707 break;
00708 case 4:
00709 *( Ceylan::Uint32 * ) p = color;
00710 break;
00711 }
00712
00713
00714 }
00715
00716 return (0);
00717
00718 }
00719
00720