OSDLPixel.cc

Go to the documentation of this file.
00001 #include "OSDLPixel.h"
00002 
00003 #include "OSDLUtils.h"           // for getBackendLastError
00004 #include "OSDLSurface.h"         // for Surface
00005 #include "OSDLOpenGL.h"          // for OpenGL color masks
00006 
00007 #include "OSDLFromGfx.h"         // taken from SDL_gfx
00008 
00009 #include "Ceylan.h"              // for CEYLAN_DETECTED_LITTLE_ENDIAN
00010 #include "SDL_gfxPrimitives.h"   // for all graphics primitives
00011 
00012 #include <list>
00013 
00014 
00015 
00016 
00017 using std::string ;
00018 
00019 
00020 using namespace Ceylan::Log ;
00021 using namespace OSDL::Video ;
00022 
00023 
00024 #ifdef OSDL_USES_CONFIG_H
00025 #include <OSDLConfig.h>          // for OSDL_DEBUG_PIXEL and al 
00026 #endif // OSDL_USES_CONFIG_H
00027 
00028 
00029 // Different colors described by name.
00030 
00031 
00032 
00034 
00035 extern const ColorDefinition OSDL::Video::Pixels::Transparent     = 
00036     {   0,   0,   0,  0  } ; 
00037 
00038 
00039 
00040 
00042 
00043 extern const ColorDefinition OSDL::Video::Pixels::Black           = 
00044     {   0,   0,   0, 255 } ; 
00045     
00046 extern const ColorDefinition OSDL::Video::Pixels::Grey            = 
00047     { 190, 190, 190, 255 } ; 
00048     
00049 extern const ColorDefinition OSDL::Video::Pixels::DimGrey         = 
00050     { 105, 105, 105, 255 } ; 
00051     
00052 extern const ColorDefinition OSDL::Video::Pixels::LightGrey       = 
00053     { 211, 211, 211, 255 } ; 
00054     
00055 extern const ColorDefinition OSDL::Video::Pixels::SlateGrey       = 
00056     { 112, 128, 144, 255 } ; 
00057 
00058 extern const ColorDefinition OSDL::Video::Pixels::Silver          = 
00059     { 230, 232, 250, 255 } ;
00060 
00061 
00062 
00063 
00065 
00066 extern const ColorDefinition OSDL::Video::Pixels::AliceBlue       = 
00067     { 240, 248, 255, 255 } ;
00068 
00069 extern const ColorDefinition OSDL::Video::Pixels::BlueViolet      = 
00070     { 138,  43, 226, 255 } ; 
00071 
00072 extern const ColorDefinition OSDL::Video::Pixels::CadetBlue       = 
00073     {  95, 158, 160, 255 } ; 
00074 
00075 extern const ColorDefinition OSDL::Video::Pixels::DarkSlateBlue   = 
00076     {  72,  61, 139, 255 } ; 
00077 
00078 extern const ColorDefinition OSDL::Video::Pixels::DarkTurquoise   = 
00079     {   0, 206, 209, 255 } ; 
00080 
00081 extern const ColorDefinition OSDL::Video::Pixels::DeepSkyBlue     = 
00082     {   0, 191, 255, 255 } ; 
00083 
00084 extern const ColorDefinition OSDL::Video::Pixels::DodgerBlue      = 
00085     {  30, 144, 255, 255 } ;
00086  
00087 extern const ColorDefinition OSDL::Video::Pixels::LightBlue       = 
00088     { 173, 216, 230, 255 } ; 
00089 
00090 extern const ColorDefinition OSDL::Video::Pixels::LightCyan       = 
00091     { 224, 255, 255, 255 } ; 
00092 
00093 extern const ColorDefinition OSDL::Video::Pixels::MediumBlue      = 
00094     { 123, 104, 238, 255 } ; 
00095 
00096 extern const ColorDefinition OSDL::Video::Pixels::NavyBlue        = 
00097     {   0,   0, 128, 255 } ;
00098  
00099 extern const ColorDefinition OSDL::Video::Pixels::RoyalBlue       = 
00100     {  65, 105, 225, 255 } ; 
00101 
00102 extern const ColorDefinition OSDL::Video::Pixels::SkyBlue         = 
00103     { 135, 206, 235, 255 } ;
00104  
00105 extern const ColorDefinition OSDL::Video::Pixels::SlateBlue       = 
00106     { 106,  90, 205, 255 } ;
00107  
00108 extern const ColorDefinition OSDL::Video::Pixels::SteelBlue       = 
00109     {  70, 130, 180, 255 } ; 
00110 
00111 extern const ColorDefinition OSDL::Video::Pixels::Aquamarine      = 
00112     { 127, 255, 212, 255 } ; 
00113 
00114 extern const ColorDefinition OSDL::Video::Pixels::Azure           = 
00115     { 240, 255, 255, 255 } ;
00116  
00117 extern const ColorDefinition OSDL::Video::Pixels::Blue            = 
00118     {   0,   0, 255, 255 } ;
00119  
00120 extern const ColorDefinition OSDL::Video::Pixels::Cyan            = 
00121     {   0, 255, 255, 255 } ;
00122  
00123 extern const ColorDefinition OSDL::Video::Pixels::Turquoise       = 
00124     {  64, 224, 208, 255 } ;
00125  
00126 extern const ColorDefinition OSDL::Video::Pixels::MidnightBlue    = 
00127     {  25,  25, 112, 255 } ; 
00128 
00129 
00130 
00131 
00133 
00134 extern const ColorDefinition OSDL::Video::Pixels::Brown           = 
00135     { 165,  42,  42, 255 } ; 
00136 
00137 extern const ColorDefinition OSDL::Video::Pixels::RosyBrown       = 
00138     { 188, 143, 143, 255 } ;
00139  
00140 extern const ColorDefinition OSDL::Video::Pixels::SaddleBrown     = 
00141     { 139,  69,  19, 255 } ; 
00142 
00143 extern const ColorDefinition OSDL::Video::Pixels::Beige           = 
00144     { 245,  42,  42, 255 } ;
00145  
00146 extern const ColorDefinition OSDL::Video::Pixels::Burlywood       = 
00147     { 222, 184, 135, 255 } ;
00148  
00149 extern const ColorDefinition OSDL::Video::Pixels::Chocolate       = 
00150     { 210, 105,  30, 255 } ; 
00151 
00152 extern const ColorDefinition OSDL::Video::Pixels::Peru            = 
00153     { 205, 133,  63, 255 } ;
00154  
00155 extern const ColorDefinition OSDL::Video::Pixels::Tan             = 
00156     { 210, 180, 140, 255 } ; 
00157 
00158 extern const ColorDefinition OSDL::Video::Pixels::Copper          = 
00159     { 184, 115,  51, 255 } ; 
00160 
00161 
00162 
00163 
00165 
00166 extern const ColorDefinition OSDL::Video::Pixels::DarkGreen       = 
00167     {   0, 100,   0, 255 } ; 
00168 
00169 extern const ColorDefinition OSDL::Video::Pixels::DarkOliveGreen  = 
00170     {  85, 107,  47, 255 } ;
00171  
00172 extern const ColorDefinition OSDL::Video::Pixels::ForestGreen     = 
00173     {  34, 139,  34, 255 } ;
00174  
00175 extern const ColorDefinition OSDL::Video::Pixels::GreenYellow     = 
00176     { 173, 255,  47, 255 } ; 
00177 
00178 extern const ColorDefinition OSDL::Video::Pixels::LawnGreen       = 
00179     { 124, 252,   0, 255 } ; 
00180 
00181 extern const ColorDefinition OSDL::Video::Pixels::LimeGreen       = 
00182     {  50, 205,  50, 255 } ;
00183  
00184 extern const ColorDefinition OSDL::Video::Pixels::MintCream       = 
00185     { 245, 255, 250, 255 } ;
00186  
00187 extern const ColorDefinition OSDL::Video::Pixels::OliveDrab       = 
00188     { 107, 142,  35, 255 } ; 
00189 
00190 extern const ColorDefinition OSDL::Video::Pixels::PaleGreen       = 
00191     { 152, 251, 152, 255 } ;
00192  
00193 extern const ColorDefinition OSDL::Video::Pixels::SeaGreen        = 
00194     {  46, 139,  87, 255 } ;
00195  
00196 extern const ColorDefinition OSDL::Video::Pixels::SpringGreen     = 
00197     {   0, 255, 127, 255 } ;
00198  
00199 extern const ColorDefinition OSDL::Video::Pixels::YellowGreen     = 
00200     { 154, 205,  50, 255 } ;
00201  
00202 extern const ColorDefinition OSDL::Video::Pixels::Chartreuse      = 
00203     { 127, 255,   0, 255 } ;
00204  
00205 extern const ColorDefinition OSDL::Video::Pixels::Green           = 
00206     {   0, 255,   0, 255 } ;
00207  
00208 extern const ColorDefinition OSDL::Video::Pixels::Khaki           = 
00209     { 240, 230, 140, 255 } ; 
00210 
00211 
00212 
00213 
00215 
00216 extern const ColorDefinition OSDL::Video::Pixels::DarkOrange      = 
00217     { 255, 140,   0, 255 } ; 
00218 
00219 extern const ColorDefinition OSDL::Video::Pixels::DarkSalmon      = 
00220     { 233, 150, 122, 255 } ;
00221  
00222 extern const ColorDefinition OSDL::Video::Pixels::LightCoral      = 
00223     { 240, 128, 128, 255 } ;
00224  
00225 extern const ColorDefinition OSDL::Video::Pixels::LightSalmon     = 
00226     { 255, 160, 122, 255 } ;
00227  
00228 extern const ColorDefinition OSDL::Video::Pixels::PeachPuff       = 
00229     { 255, 218, 185, 255 } ;
00230  
00231 extern const ColorDefinition OSDL::Video::Pixels::Bisque          = 
00232     { 255, 228, 196, 255 } ;
00233  
00234 extern const ColorDefinition OSDL::Video::Pixels::Coral           = 
00235     { 255, 127,  80, 255 } ; 
00236 
00237 extern const ColorDefinition OSDL::Video::Pixels::Honeydew        = 
00238     { 240, 255, 240, 255 } ;
00239  
00240 extern const ColorDefinition OSDL::Video::Pixels::Orange          = 
00241     { 255, 165,   0, 255 } ;
00242  
00243 extern const ColorDefinition OSDL::Video::Pixels::Salmon          = 
00244     { 250, 128, 114, 255 } ;
00245  
00246 extern const ColorDefinition OSDL::Video::Pixels::Sienna          = 
00247     { 160,  82,  45, 255 } ; 
00248 
00249 
00250 
00251 
00253 
00254 extern const ColorDefinition OSDL::Video::Pixels::DeepPink        = 
00255     { 255,  20, 147, 255 } ;
00256  
00257 extern const ColorDefinition OSDL::Video::Pixels::HotPink         = 
00258     { 255, 105, 180, 255 } ;
00259  
00260 extern const ColorDefinition OSDL::Video::Pixels::IndianRed       = 
00261     { 205,  92,  92, 255 } ;
00262  
00263 extern const ColorDefinition OSDL::Video::Pixels::LightPink       = 
00264     { 255, 182, 193, 255 } ;
00265  
00266 extern const ColorDefinition OSDL::Video::Pixels::MediumVioletRed = 
00267     { 199,  21, 133, 255 } ;
00268  
00269 extern const ColorDefinition OSDL::Video::Pixels::MistyRose       = 
00270     { 255, 228, 225, 255 } ;
00271  
00272 extern const ColorDefinition OSDL::Video::Pixels::OrangeRed       = 
00273     { 255,  69,   0, 255 } ;
00274  
00275 extern const ColorDefinition OSDL::Video::Pixels::VioletRed       = 
00276     { 208,  32, 144, 255 } ;
00277  
00278 extern const ColorDefinition OSDL::Video::Pixels::Firebrick       = 
00279     { 178,  34, 34 , 255 } ;
00280  
00281 extern const ColorDefinition OSDL::Video::Pixels::Pink            = 
00282     { 255, 192, 203, 255 } ; 
00283 
00284 extern const ColorDefinition OSDL::Video::Pixels::Red             = 
00285     { 255,   0,   0, 255 } ; 
00286 
00287 extern const ColorDefinition OSDL::Video::Pixels::Tomato          = 
00288     { 255,  99,  71, 255 } ;
00289  
00290 
00291 
00292 
00294 
00295 extern const ColorDefinition OSDL::Video::Pixels::DarkOrchid      = 
00296     { 153,  50, 204, 255 } ;
00297  
00298 extern const ColorDefinition OSDL::Video::Pixels::DarkViolet      = 
00299     { 148,   0, 211, 255 } ;
00300  
00301 extern const ColorDefinition OSDL::Video::Pixels::LavenderBlush   = 
00302     { 255, 240, 245, 255 } ;
00303  
00304 extern const ColorDefinition OSDL::Video::Pixels::MediumOrchid    = 
00305     { 186,  85, 211, 255 } ;
00306  
00307 extern const ColorDefinition OSDL::Video::Pixels::MediumPurple    = 
00308     { 147, 112, 219, 255 } ;
00309  
00310 extern const ColorDefinition OSDL::Video::Pixels::Lavender        = 
00311     { 230, 230, 250, 255 } ;
00312  
00313 extern const ColorDefinition OSDL::Video::Pixels::Magenta         = 
00314     { 255,   0, 255, 255 } ;
00315  
00316 extern const ColorDefinition OSDL::Video::Pixels::Maroon          = 
00317     { 176,  48,  96, 255 } ;
00318  
00319 extern const ColorDefinition OSDL::Video::Pixels::Orchid          = 
00320     { 218, 112, 214, 255 } ;
00321  
00322 extern const ColorDefinition OSDL::Video::Pixels::Plum            = 
00323     { 221, 160, 221, 255 } ;
00324  
00325 extern const ColorDefinition OSDL::Video::Pixels::Purple          = 
00326     { 160,  32, 240, 255 } ;
00327  
00328 extern const ColorDefinition OSDL::Video::Pixels::Thistle         = 
00329     { 216, 191, 216, 255 } ;
00330  
00331 extern const ColorDefinition OSDL::Video::Pixels::Violet          = 
00332     { 238, 130, 238, 255 } ;
00333  
00334 
00335 
00336 
00338 
00339 extern const ColorDefinition OSDL::Video::Pixels::AntiqueWhite    = 
00340     { 250, 235, 215, 255 } ;
00341  
00342 extern const ColorDefinition OSDL::Video::Pixels::FloralWhite     = 
00343     { 255, 250, 240, 255 } ;
00344  
00345 extern const ColorDefinition OSDL::Video::Pixels::GhostWhite      = 
00346     { 248, 248, 255, 255 } ;
00347  
00348 extern const ColorDefinition OSDL::Video::Pixels::NavajoWhite     = 
00349     { 255, 222, 173, 255 } ;
00350  
00351 extern const ColorDefinition OSDL::Video::Pixels::OldLace         = 
00352     { 253, 245, 230, 255 } ;
00353  
00354 extern const ColorDefinition OSDL::Video::Pixels::WhiteSmoke      = 
00355     { 245, 245, 245, 255 } ;
00356  
00357 extern const ColorDefinition OSDL::Video::Pixels::Gainsboro       = 
00358     { 220, 220, 220, 255 } ;
00359  
00360 extern const ColorDefinition OSDL::Video::Pixels::Ivory           = 
00361     { 255, 255, 240, 255 } ;
00362  
00363 extern const ColorDefinition OSDL::Video::Pixels::Linen           = 
00364     { 250, 240, 230, 255 } ;
00365  
00366 extern const ColorDefinition OSDL::Video::Pixels::Seashell        = 
00367     { 255, 245, 238, 255 } ;
00368  
00369 extern const ColorDefinition OSDL::Video::Pixels::Snow            = 
00370     { 255, 250, 250, 255 } ;
00371  
00372 extern const ColorDefinition OSDL::Video::Pixels::Wheat           = 
00373     { 245, 222, 179, 255 } ;
00374  
00375 extern const ColorDefinition OSDL::Video::Pixels::White           = 
00376     { 255, 255, 255, 255 } ; 
00377 
00378 
00379 
00380 
00382 
00383 extern const ColorDefinition OSDL::Video::Pixels::BlanchedAlmond  = 
00384     { 255, 235, 205, 255 } ;
00385  
00386 extern const ColorDefinition OSDL::Video::Pixels::DarkGoldenrod   = 
00387     { 184, 134,  11, 255 } ;
00388  
00389 extern const ColorDefinition OSDL::Video::Pixels::LemonChiffon    = 
00390     { 255, 250, 205, 255 } ;
00391  
00392 extern const ColorDefinition OSDL::Video::Pixels::LightGoldenrod  = 
00393     { 238, 221, 130, 255 } ;
00394  
00395 extern const ColorDefinition OSDL::Video::Pixels::LightYellow     = 
00396     { 255, 255, 224, 255 } ;
00397  
00398 extern const ColorDefinition OSDL::Video::Pixels::PaleGoldenrod   = 
00399     { 238, 232, 170, 255 } ;
00400  
00401 extern const ColorDefinition OSDL::Video::Pixels::PapayaWhip      = 
00402     { 255, 239, 213, 255 } ;
00403  
00404 extern const ColorDefinition OSDL::Video::Pixels::Cornsilk        = 
00405     { 255, 248, 220, 255 } ;
00406  
00407 extern const ColorDefinition OSDL::Video::Pixels::Gold            = 
00408     { 255, 215,   0, 255 } ;
00409  
00410 extern const ColorDefinition OSDL::Video::Pixels::Goldenrod       = 
00411     { 218, 165,  32, 255 } ;
00412  
00413 extern const ColorDefinition OSDL::Video::Pixels::Moccasin        = 
00414     { 255, 228, 181, 255 } ;
00415  
00416 extern const ColorDefinition OSDL::Video::Pixels::Yellow          = 
00417     { 255, 255,   0, 255 } ; 
00418 
00419 
00420 
00421 
00422 bool Pixels::setGamma( GammaFactor red, GammaFactor green, GammaFactor blue )
00423     throw()
00424 {
00425 
00426     if ( SDL_SetGamma( red, green, blue ) == -1 )
00427     {
00428         LogPlug::error( "Pixels::setGamma : " 
00429             + Utils::getBackendLastError() ) ;
00430         return false ;
00431     }
00432     
00433     return true ;
00434     
00435 }
00436 
00437 
00438 
00439 bool Pixels::setGammaRamp( GammaRampElement * redRamp, 
00440     GammaRampElement * greenRamp, GammaRampElement * blueRamp ) throw()
00441 {
00442 
00443     if ( SDL_SetGammaRamp( redRamp, greenRamp, blueRamp ) == -1 )
00444     {
00445         LogPlug::error( "Pixels::setGammaRamp : " 
00446             + Utils::getBackendLastError() ) ;
00447         return false ;
00448     }
00449     
00450     return true ;
00451 
00452 }   
00453 
00454 
00455 
00456 bool Pixels::getGammaRamp( GammaRampElement * redRamp, 
00457     GammaRampElement * greenRamp, GammaRampElement * blueRamp ) throw()
00458 {
00459 
00460     if ( SDL_GetGammaRamp( redRamp, greenRamp, blueRamp ) == -1 )
00461     {
00462         LogPlug::error( "Pixels::getGammaRamp : " 
00463             + Utils::getBackendLastError() ) ;
00464         return false ;
00465     }
00466     
00467     return true ;
00468 
00469 }   
00470 
00471 
00472 
00473 // Color masks.
00474 
00475 
00476 void Pixels::getRecommendedColorMasks( ColorMask & redMask, 
00477     ColorMask & greenMask, ColorMask & blueMask, 
00478     ColorMask & alphaMask ) throw()
00479 {
00480 
00481 
00482 #if OSDL_DEBUG_PIXEL
00483 
00484     // Check endianness here just to output a log message :
00485     
00486 #if CEYLAN_DETECTED_LITTLE_ENDIAN
00487 
00488     LogPlug::debug( "Pixels::getRecommendedColorMasks (with alpha): "
00489         "using little endian convention." ) ;
00490         
00491 #else // CEYLAN_DETECTED_LITTLE_ENDIAN
00492 
00493     LogPlug::debug( "Pixels::getRecommendedColorMasks (with alpha): "
00494         "using big endian convention." ) ;
00495         
00496 #endif // CEYLAN_DETECTED_LITTLE_ENDIAN
00497 
00498 #endif // OSDL_DEBUG_PIXEL
00499     
00500     /*
00501      * Ensure color masks are only defined once (in OpenGL module) to 
00502      * avoid disaster :
00503      *
00504      */
00505     
00506     redMask   = OpenGL::RedMask ;
00507     greenMask = OpenGL::GreenMask ;
00508     blueMask  = OpenGL::BlueMask ;
00509     alphaMask = OpenGL::AlphaMask ;
00510         
00511 }   
00512                                 
00513     
00514                 
00515 void Pixels::getRecommendedColorMasks( ColorMask & redMask, 
00516     ColorMask & greenMask, ColorMask & blueMask ) throw()
00517 {
00518 
00519 
00520 #if OSDL_DEBUG_PIXEL
00521 
00522     // Check endianness here just to output a log message :
00523     
00524 #if CEYLAN_DETECTED_LITTLE_ENDIAN
00525 
00526     LogPlug::debug( "Pixels::getRecommendedColorMasks (with alpha): "
00527         "using little endian convention." ) ;
00528         
00529 #else // CEYLAN_DETECTED_LITTLE_ENDIAN
00530 
00531     LogPlug::debug( "Pixels::getRecommendedColorMasks (with alpha): "
00532         "using big endian convention." ) ;
00533         
00534 #endif // CEYLAN_DETECTED_LITTLE_ENDIAN
00535 
00536 #endif // OSDL_DEBUG_PIXEL
00537 
00538 
00539     redMask   = OpenGL::RedMask ;
00540     greenMask = OpenGL::GreenMask ;
00541     blueMask  = OpenGL::BlueMask ;
00542 
00543 }   
00544                 
00545 
00546 
00547 void Pixels::getCurrentColorMasks( const Pixels::PixelFormat & format, 
00548     Pixels::ColorMask & redMask,  Pixels::ColorMask & greenMask, 
00549     Pixels::ColorMask & blueMask, Pixels::ColorMask & alphaMask ) throw()
00550 {
00551 
00552     redMask   = format.Rmask ;
00553     greenMask = format.Gmask ;
00554     blueMask  = format.Bmask ;
00555     alphaMask = format.Amask ;
00556         
00557 }
00558 
00559 
00560 
00561 // Color conversion section.
00562 
00563 
00564 ColorDefinition Pixels::convertRGBAToColorDefinition( 
00565     ColorElement red,  ColorElement green, 
00566     ColorElement blue, ColorElement alpha ) throw()
00567 {
00568 
00569     ColorDefinition result ;
00570     
00571     result.r      = red ;
00572     result.g      = green ; 
00573     result.b      = blue ;  
00574     result.unused = alpha ; 
00575     
00576     return result ;
00577 }
00578     
00579     
00580                 
00581 void Pixels::convertColorDefinitionToRGBA( ColorDefinition color,
00582     ColorElement & red, ColorElement & green, ColorElement & blue, 
00583     ColorElement & alpha ) throw() 
00584 {
00585 
00586     red   = color.r ;
00587     green = color.g ;
00588     blue  = color.b ;
00589     alpha = color.unused ;
00590     
00591 }   
00592                             
00593 
00594                 
00595 PixelColor Pixels::convertRGBAToPixelColor( const Pixels::PixelFormat & format,
00596     ColorElement red, ColorElement green, ColorElement blue, 
00597     ColorElement alpha ) throw() 
00598 {   
00599 
00600     /*
00601     
00602     LogPlug::debug( "convertRGBAToPixelColor : pixel format is " 
00603         + Pixels::toString( format ) + ", pixel is [ R, G, B, A ] = [ "
00604                 + Ceylan::toString( static_cast<Uint16>( red ) ) )   + " ; "
00605                 + Ceylan::toString( static_cast<Uint16>( green ) ) + " ; "
00606                 + Ceylan::toString( static_cast<Uint16>( blue  ) )  + " ; "
00607                 + Ceylan::toString( static_cast<Uint16>( alpha ) )  + " ] " ) ;
00608     */
00609                 
00610     return SDL_MapRGBA( const_cast<Pixels::PixelFormat *>( & format ), 
00611         red, green, blue, alpha ) ;
00612     
00613 }
00614 
00615 
00616 
00617 ColorDefinition Pixels::convertPixelColorToColorDefinition(
00618      const PixelFormat & format, PixelColor pixel ) throw()
00619 {
00620 
00621     ColorDefinition pixDef ;
00622 
00623     SDL_GetRGBA( pixel, const_cast<Pixels::PixelFormat *>( & format ), 
00624         & pixDef.r, & pixDef.g, & pixDef.b, & pixDef.unused ) ;
00625     
00626     return pixDef ;
00627     
00628 }
00629 
00630 
00631 
00632 PixelColor Pixels::convertColorDefinitionToPixelColor( 
00633     const PixelFormat & format, ColorDefinition colorDef ) throw()
00634 {
00635 
00636     return SDL_MapRGBA( const_cast<Pixels::PixelFormat *>( & format ),
00637         colorDef.r, colorDef.g, colorDef.b, colorDef.unused ) ;
00638     
00639 }
00640 
00641 
00642 
00643 PixelColor Pixels::convertColorDefinitionToRawPixelColor( 
00644     ColorDefinition colorDef ) throw()
00645 {
00646 
00647     /*
00648      * This is a very artificial transformation, requested by the compiler :
00649      * from a set of four bytes (struct SDL_Color) to a Uint32...
00650      *
00651      */
00652     return ((Ceylan::Uint32) colorDef.r << 24) 
00653          | ((Ceylan::Uint32) colorDef.g << 16) 
00654          | ((Ceylan::Uint32) colorDef.b << 8 ) 
00655          | ((Ceylan::Uint32) colorDef.unused ) ;
00656          
00657 }
00658 
00659 
00660 
00661 PixelColor Pixels::convertRGBAToRawPixelColor( 
00662     ColorElement red, ColorElement green, ColorElement blue, 
00663     ColorElement alpha ) throw()
00664 {
00665     return ((Uint32) red << 24) | ((Uint32) green << 16) 
00666          | ((Uint32) blue << 8) | ((Uint32) alpha ) ;
00667     
00668 }
00669 
00670 
00671 
00672 
00673 // Color comparisons section.
00674 
00675 
00676 bool Pixels::areEqual( ColorDefinition first, ColorDefinition second, 
00677     bool useAlpha ) throw()
00678 {
00679     
00680 
00681 #if OSDL_DEBUG_COLOR
00682     LogPlug::trace( "Pixels::areEqual : comparing " 
00683         + Pixels::toString( first ) + " with "
00684         + Pixels::toString( second ) 
00685         + ( useAlpha ? " (alpha taken into account)" : " (alpha ignored)" ) ) ;
00686 #endif // OSDL_DEBUG_COLOR
00687     
00688     if ( first.r != second.r )
00689         return false ;
00690 
00691     if ( first.g != second.g )
00692         return false ;
00693         
00694     if ( first.b != second.b )
00695         return false ;
00696 
00697     if ( useAlpha )
00698         return ( first.unused == second.unused ) ;
00699     else
00700         return true ;   
00701         
00702 }
00703 
00704 
00705 
00706 bool Pixels::isLess( ColorDefinition value, ColorDefinition comparison ) throw()
00707 {
00708 
00709     if ( value.r < comparison.r )
00710         return true ;
00711         
00712     if ( value.r > comparison.r )
00713         return false ;
00714         
00715         
00716     if ( value.g < comparison.g )
00717         return true ;
00718         
00719     if ( value.g > comparison.g )
00720         return false ;
00721         
00722         
00723     if ( value.b < comparison.b )
00724         return true ;
00725         
00726     if ( value.b > comparison.b )
00727         return false ;
00728         
00729         
00730     if ( value.unused < comparison.unused )
00731         return true ;
00732     
00733     if ( value.unused > comparison.unused )
00734         return false ;
00735     
00736     return false ;  
00737         
00738 }                   
00739 
00740 
00741 
00742 bool Pixels::areEqual( PixelColor first, PixelColor second ) throw()
00743 {
00744 
00745     return first == second ;
00746     
00747 }
00748 
00749 
00750         
00751 ColorDefinition Pixels::selectColorDifferentFrom( ColorDefinition first, 
00752     ColorDefinition second ) throw()    
00753 {
00754 
00755     // Three different choices are always enough :
00756     ColorDefinition res = Pixels::Red ;
00757     
00758     if ( ( ! areEqual( res, first, /* useAlpha */ false ) ) 
00759             && ( ! areEqual( res, second, /* useAlpha */ false ) ) )
00760         return res ;
00761     
00762     res = Pixels::Green ;
00763         
00764     if ( ( ! areEqual( res, first, /* useAlpha */ false ) ) 
00765             && ( ! areEqual( res, second, /* useAlpha */ false ) ) )
00766         return res ;
00767     
00768     return Pixels::Blue ;
00769             
00770 }
00771     
00772         
00773         
00774 ColorDefinition Pixels::selectColorDifferentFrom( ColorDefinition first, 
00775     ColorDefinition second, ColorDefinition third ) throw()     
00776 {
00777 
00778     // Four different choices are always enough :
00779     ColorDefinition res = Pixels::Red ;
00780     
00781     if ( ( ! areEqual( res, first, /* useAlpha */ false ) ) 
00782         && ( ! areEqual( res, second, /* useAlpha */ false  ) 
00783             && ( ! areEqual( res, third, /* useAlpha */ false ) ) ) )
00784         return res ;
00785     
00786     res = Pixels::Green ;
00787         
00788     if ( ( ! areEqual( res, first, /* useAlpha */ false ) ) 
00789         && ( ! areEqual( res, second, /* useAlpha */ false  ) 
00790             && ( ! areEqual( res, third, /* useAlpha */ false ) ) ) )
00791         return res ;
00792     
00793     res = Pixels::Blue ;
00794         
00795     if ( ( ! areEqual( res, first, /* useAlpha */ false ) ) 
00796         && ( ! areEqual( res, second, /* useAlpha */ false  ) 
00797             && ( ! areEqual( res, third, /* useAlpha */ false ) ) ) )
00798         return res ;
00799     
00800     return Pixels::Black ;
00801     
00802 }
00803         
00804         
00805 
00806 // get/put pixel operations.
00807 
00808 
00809 Pixels::PixelColor Pixels::getPixelColor( const Surface & fromSurface,
00810     Coordinate x, Coordinate y ) throw ( VideoException )
00811 {
00812 
00813     BytesPerPixel bpp = fromSurface.getBytesPerPixel() ;
00814     
00815     /*
00816      * Here p is the address to the pixel whose color we want to 
00817      * retrieve :
00818      *
00819      */
00820     Uint8 * p = reinterpret_cast<Uint8 *>( fromSurface.getPixels() )
00821         + y * fromSurface.getPitch() + x * bpp ;
00822 
00823     switch( bpp ) 
00824     {
00825     
00826         case 1:
00827             return * p ;
00828 
00829         case 2:
00830             return *( Uint16 * ) p ;
00831 
00832          case 3:
00833 #if CEYLAN_DETECTED_LITTLE_ENDIAN        
00834             return p[0] | ( p[1] << 8 ) | p[2] << 16 ;
00835 #else // CEYLAN_DETECTED_LITTLE_ENDIAN
00836             return ( p[0] << 16 ) | ( p[1] << 8 ) | p[2] ;
00837 #endif // CEYLAN_DETECTED_LITTLE_ENDIAN
00838  
00839         case 4:
00840             return *( Uint32 * ) p ;
00841     
00842         default:
00843             throw VideoException( "Abnormal bit per pixel detected "
00844                 "in Pixels::getPixelColor" ) ;
00845     }
00846     
00847 } 
00848 
00849 
00850 
00851 Pixels::ColorDefinition Pixels::getColorDefinition( 
00852         const Surface & fromSurface, Coordinate x, Coordinate y ) 
00853     throw ( VideoException )
00854 {
00855 
00856     return convertPixelColorToColorDefinition( fromSurface.getPixelFormat(),
00857         getPixelColor( fromSurface, x, y ) ) ;
00858         
00859 }
00860 
00861 
00862 
00863         
00864 void Pixels::putRGBAPixel( Surface & targetSurface, 
00865         Coordinate x, Coordinate y, 
00866         ColorElement red, ColorElement green, ColorElement blue, 
00867         ColorElement alpha, bool blending, bool clipping, bool locking ) 
00868     throw( VideoException )
00869 {
00870 
00871     putPixelColor( targetSurface, x, y, 
00872         convertRGBAToPixelColor( targetSurface.getPixelFormat(), 
00873             red, green, blue, alpha ), alpha, blending, clipping, locking ) ;
00874 
00875 }
00876 
00877 
00878 
00879 void Pixels::putColorDefinition( Surface & targetSurface, 
00880         Coordinate x, Coordinate y, ColorDefinition colorDef, 
00881         bool blending, bool clipping, bool locking )
00882     throw( VideoException )
00883 {
00884 
00885     putPixelColor( targetSurface, x, y, 
00886         convertRGBAToPixelColor( targetSurface.getPixelFormat(), 
00887             colorDef.r, colorDef.g, colorDef.b, colorDef.unused ), 
00888         colorDef.unused, blending, clipping, locking ) ;
00889         
00890 }   
00891 
00892 
00893 
00894 void Pixels::putPixelColor( Surface & targetSurface, 
00895         Coordinate x, Coordinate y, PixelColor convertedColor, 
00896         ColorElement alpha, bool blending, bool clipping, bool locking ) 
00897     throw( VideoException )
00898 {
00899     
00900     /*
00901      * The lock method is conditional, mustBeLocked() tests could not be used.
00902      *
00903      */
00904 
00905     /* 
00906      * Selects the right SDL_gfx primitive to call :
00907      * [ blending, clipping, locking ] = [ B, C, L ]
00908      *
00909      */
00910     
00911     if ( locking )
00912     {
00913         
00914         if ( clipping )
00915         {
00916         
00917             if ( blending )
00918             {
00919             
00920                 // [ B, C, L ] = [ 1, 1, 1 ]
00921                 
00922                 if ( targetSurface.mustBeLocked() )
00923                 {   
00924                     targetSurface.lock() ;
00925 					
00926 					::putPixelAlpha( & targetSurface.getSDLSurface(), x, y, 
00927                         convertedColor, alpha ) ;
00928                     
00929                     targetSurface.unlock() ;                                
00930                 }
00931                 else
00932                 {
00933 					::putPixelAlpha( & targetSurface.getSDLSurface(), x, y, 
00934                         convertedColor, alpha ) ;   
00935                 }
00936                 
00937             }
00938             else // blending is false :
00939             {
00940             
00941                 // [ B, C, L ] = [ 0, 1, 1 ]
00942 
00943                 if ( targetSurface.mustBeLocked() )
00944                 {   
00945                     targetSurface.lock() ;
00946 					
00947 					::fastPixelColorNolock( & targetSurface.getSDLSurface(), 
00948                         x, y, convertedColor ) ;
00949                                 
00950                     targetSurface.unlock() ;                                
00951                 }
00952                 else
00953                 {
00954 					::fastPixelColorNolock( & targetSurface.getSDLSurface(), 
00955                         x, y, convertedColor ) ;            
00956                 }
00957                     
00958             } // end blending
00959         
00960         } 
00961         else // clipping is false (beware !) :
00962         {
00963         
00964             if ( blending )
00965             {
00966             
00967                 // [ B, C, L ] = [ 1, 0, 1 ]
00968             
00969                 /*
00970                  * Clipping is done nevertheless (cannot be disabled, not 
00971                  * that bad).
00972                  *
00973                  */
00974                 
00975                 if ( targetSurface.mustBeLocked() )
00976                 {   
00977                     targetSurface.lock() ;
00978 					::putPixelAlpha( & targetSurface.getSDLSurface(), x, y, 
00979                         convertedColor, alpha ) ;
00980                     targetSurface.unlock() ;                                
00981                 }
00982                 else
00983                 {
00984 					::putPixelAlpha( & targetSurface.getSDLSurface(), x, y, 
00985                         convertedColor, alpha ) ;   
00986                 }
00987             
00988             
00989             }
00990             else // blending is false :
00991             {
00992             
00993                 // [ B, C, L ] = [ 0, 0, 1 ]
00994             
00995                 // This time, clipping is *not* performed, as wanted...
00996                 
00997                 if ( targetSurface.mustBeLocked() )
00998                 {   
00999                     targetSurface.lock() ;
01000 					::fastPixelColorNolockNoclip( 
01001                         & targetSurface.getSDLSurface(), 
01002                         x, y, convertedColor ) ;
01003                     targetSurface.unlock() ;                                
01004                 }
01005                 else
01006                 {
01007 					::fastPixelColorNolockNoclip( 
01008                         & targetSurface.getSDLSurface(), 
01009                         x, y, convertedColor ) ;        
01010                 }
01011             
01012                                 
01013             } // end blending
01014         
01015         
01016         } // end clipping
01017         
01018         
01019     } 
01020     else // locking is false :
01021     {
01022 
01023         if ( clipping )
01024         {
01025 
01026     
01027             if ( blending )
01028             {
01029             
01030                 // [ B, C, L ] = [ 1, 1, 0 ]
01031                 
01032                 // This is the most commonly used case !
01033                 
01034                 //alternativePut( targetSurface, x, y, convertedColor ) ;   
01035 				::putPixelAlpha( & targetSurface.getSDLSurface(), x, y, 
01036                     convertedColor, alpha ) ;           
01037                     
01038             }
01039             else // blending is false :
01040             {       
01041             
01042                 // [ B, C, L ] = [ 0, 1, 0 ]
01043 				
01044 				::fastPixelColorNolock( & targetSurface.getSDLSurface(), 
01045                     x, y, convertedColor ) ;
01046                 
01047             } // end blending
01048     
01049         } 
01050         else // clipping is false (beware !) :
01051         {
01052         
01053             if ( blending )
01054             {
01055 
01056                 // [ B, C, L ] = [ 1, 0, 0 ]
01057 
01058                 // Actually the clipping is made in this case too.
01059 				::putPixelAlpha( & targetSurface.getSDLSurface(), x, y, 
01060                     convertedColor, alpha ) ;   
01061                 
01062             }
01063             else // blending is false :
01064             {
01065             
01066                 // [ B, C, L ] = [ 0, 0, 0 ]
01067 				
01068 				::fastPixelColorNolockNoclip( & targetSurface.getSDLSurface(), 
01069                     x, y, convertedColor ) ;
01070             
01071             } // end blending
01072         
01073         
01074         } // end clipping
01075 
01076 
01077     } // end locking
01078 
01079 
01080 }
01081 
01082 
01083 
01084 void Pixels::alternativePutPixelColor( Surface & targetSurface, 
01085     Coordinate x, Coordinate y, PixelColor color, bool mapToSurfaceFormat )
01086         throw()
01087 {
01088 
01089     /*
01090     
01091     LogPlug::debug( "Pixels::alternativePut called for point in [ "
01092         + Ceylan::toString( x ) + " ; " 
01093         + Ceylan::toString( y ) + " ] with pixel color "
01094         + Ceylan::toString( color ) 
01095         + " (" + Ceylan::toString( color, true ) + " )." ) ;
01096     
01097     */
01098 
01099     ColorMask redMask, greenMask, blueMask, alphaMask ;
01100     Pixels::getRecommendedColorMasks( redMask, greenMask, blueMask, 
01101         alphaMask ) ;
01102 
01103     if ( mapToSurfaceFormat )
01104     {
01105         color = SDL_MapRGBA( & targetSurface.getPixelFormat(), 
01106             ( color & redMask   ) >> 24,
01107             ( color & greenMask ) >> 16, 
01108             ( color & blueMask  ) >>  8,
01109               color & alphaMask ) ;
01110     }
01111                     
01112     BytesPerPixel bytes = targetSurface.getBytesPerPixel() ;
01113     
01114     // Here p is the address of the pixel whose color is to be set :
01115     ColorElement * p = reinterpret_cast<ColorElement *>(
01116             targetSurface.getPixels() ) 
01117             + y * targetSurface.getPitch() + x * bytes ;
01118 
01119     switch( bytes ) 
01120     {
01121     
01122         case 1:
01123             *p = color ;
01124             break ;
01125 
01126         case 2:
01127             *( Uint16 * ) p = color ;
01128             break ;
01129 
01130         case 3:
01131 #if CEYLAN_DETECTED_LITTLE_ENDIAN
01132                 p[0] =   color         & 0xff ;
01133                 p[1] = ( color >> 8  ) & 0xff ;
01134                 p[2] = ( color >> 16 ) & 0xff ;
01135 #else // CEYLAN_DETECTED_LITTLE_ENDIAN
01136                 p[0] = ( color >> 16 ) & 0xff ;
01137                 p[1] = ( color >>  8 ) & 0xff ;
01138                 p[2] =   color         & 0xff ;
01139 #endif // CEYLAN_DETECTED_LITTLE_ENDIAN     
01140             break ;
01141 
01142         case 4:
01143             *( Uint32 * ) p = color ;
01144             break ;
01145             
01146         default:
01147             LogPlug::error( "Pixels::alternativePut : "
01148                 "unexpected bytes per pixel specified ("
01149                 + Ceylan::toString( 
01150                     static_cast<Ceylan::Uint16>( bytes ) ) 
01151                 + "), nothing done." ) ;
01152             break ;
01153             
01154     }
01155 }
01156 
01157 
01158     
01159 string Pixels::toString( const Pixels::PixelFormat & format ) throw()
01160 {
01161 
01162     string result = "Pixel format description "
01163         "(masks are binary masks used to retrieve individual color values, "
01164         "loss is the precision loss of each color component, "
01165         "shift correspond to binary left shifts of each "
01166         "color component in the pixel value) : " ;
01167 
01168     std::list<string> l ;
01169 
01170     l.push_back( Ceylan::toNumericalString( format.BitsPerPixel ) 
01171         + " bits per pixel." ) ;
01172         
01173     l.push_back( Ceylan::toNumericalString( format.BytesPerPixel ) 
01174         + " bytes per pixel." ) ;
01175 
01176     l.push_back( "Colorkey (pixel value of transparent pixels) is " 
01177         + Ceylan::toNumericalString( format.colorkey ) + "." ) ;
01178         
01179     l.push_back( "Overall alpha is " 
01180         + Ceylan::toNumericalString( format.alpha ) + "." ) ;
01181     
01182     if ( format.palette )
01183         l.push_back( "Palette available." ) ;
01184     else
01185         l.push_back( "No palette used." ) ;
01186         
01187     
01188     l.push_back( "Rmask is " + Ceylan::toString( format.Rmask, true ) + "." ) ;
01189     l.push_back( "Gmask is " + Ceylan::toString( format.Gmask, true ) + "." ) ;
01190     l.push_back( "Bmask is " + Ceylan::toString( format.Bmask, true ) + "." ) ;
01191     l.push_back( "Amask is " + Ceylan::toString( format.Amask, true ) + "." ) ;
01192 
01193     l.push_back( "Rshift is " 
01194         + Ceylan::toNumericalString( format.Rshift ) + "." ) ;
01195         
01196     l.push_back( "Gshift is " 
01197         + Ceylan::toNumericalString( format.Gshift ) + "." ) ;
01198         
01199     l.push_back( "Bshift is " 
01200         + Ceylan::toNumericalString( format.Bshift ) + "." ) ;
01201         
01202     l.push_back( "Ashift is " 
01203         + Ceylan::toNumericalString( format.Ashift ) + "." ) ;
01204         
01205     l.push_back( "Rloss is " 
01206         + Ceylan::toNumericalString( format.Rloss ) + "." ) ;
01207         
01208     l.push_back( "Gloss is " 
01209         + Ceylan::toNumericalString( format.Gloss ) + "." ) ;
01210         
01211     l.push_back( "Bloss is " 
01212         + Ceylan::toNumericalString( format.Bloss ) + "." ) ;
01213         
01214     l.push_back( "Aloss is " 
01215         + Ceylan::toNumericalString( format.Aloss ) + "." ) ;
01216     
01217         
01218     return result + Ceylan::formatStringList( l ) ;
01219     
01220 }
01221 
01222 
01223 
01224 string Pixels::toString( PixelColor pixel, const PixelFormat & format ) throw()
01225 {
01226 
01227     return "Pixel whose color definition is " 
01228         + toString( convertPixelColorToColorDefinition( format, pixel ) ) ; 
01229     
01230 }
01231             
01232         
01233                 
01234 string Pixels::toString( ColorDefinition color ) throw() 
01235 {
01236     
01237     string result = "[R;G;B;A] = [ " 
01238             + Ceylan::toNumericalString( color.r ) + " ; "
01239             + Ceylan::toNumericalString( color.g ) + " ; "
01240             + Ceylan::toNumericalString( color.b ) + " ; "
01241             + Ceylan::toNumericalString( color.unused ) + " ] " ;
01242             
01243     if ( Ceylan::TextDisplayable::GetOutputFormat() 
01244         == Ceylan::TextDisplayable::html )
01245     {
01246     
01247         string hexcolor = Ceylan::toHexString( color.r, 
01248                 /* prefix */ false, /* minDigits */ 2 ) 
01249             + Ceylan::toHexString( color.g ,
01250                 /* prefix */ false, /* minDigits */ 2 ) 
01251             + Ceylan::toHexString( color.b , 
01252                 /* prefix */ false, /* minDigits */ 2 ) ;
01253         
01254         /*
01255          * Some characters have to be displayed so that the HTML table 
01256          * cell is drawn :
01257          *
01258          */
01259         result += "<table><tr><td style=\"background : #" 
01260             + hexcolor + "; color : #" 
01261             + hexcolor + "\">OSDL rocks !</td></tr></table>" ;
01262 
01263     }
01264     
01265     return result ;
01266     
01267 }
01268 

Generated on Fri Mar 30 14:46:59 2007 for OSDL by  doxygen 1.5.1