00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef blitterH
00022 #define blitterH
00023
00024 #include <cmath>
00025 #include <map>
00026 #include "../libs/loki/static_check.h"
00027 #include "../libs/sdlmm/src/sdlmm.h"
00028 #include "surface.h"
00029
00030 #include "../misc.h"
00031 #include "../palette.h"
00032 #include "../basegfx.h"
00033
00034 typedef SDLmm::Color Color;
00035
00036 class NullParamType
00037 {}
00038 ;
00039 extern NullParamType nullParam;
00040
00041
00042 template<int BytesPerPixel>
00043 class PixelSize2Type;
00044
00045 template<>
00046 class PixelSize2Type<1>
00047 {
00048 public:
00049 typedef Uint8 PixelType;
00050 };
00051 template<>
00052 class PixelSize2Type<2>
00053 {
00054 public:
00055 typedef Uint16 PixelType;
00056 };
00057 template<>
00058 class PixelSize2Type<4>
00059 {
00060 public:
00061 typedef Uint32 PixelType;
00062 };
00063
00064
00065
00066 class TargetPixelSelector_All
00067 {
00068 protected:
00069 int skipTarget( int x, int y )
00070 {
00071 return 0;
00072 };
00073 void init( const Surface& srv, const SPoint& pos, int xrange, int yrange )
00074 {}
00075 ;
00076 public:
00077 TargetPixelSelector_All ( NullParamType npt = nullParam )
00078 {}
00079 ;
00080 };
00081
00082 class TargetPixelSelector_Valid
00083 {
00084 int w,h;
00085 int xrange;
00086 SPoint dstPos;
00087 protected:
00088 int skipTarget( int x, int y )
00089 {
00090 x += dstPos.x;
00091 y += dstPos.y;
00092
00093 if ( x >= 0 && y >= 0 && x < w && y < h )
00094 return 0;
00095 else
00096 if ( x < 0 )
00097 return -x;
00098 else
00099 return xrange - x + dstPos.x;
00100 };
00101 void init( const Surface& srv, const SPoint& pos, int xrange, int yrange )
00102 {
00103 w = srv.w();
00104 h = srv.h();
00105 dstPos = pos;
00106 this->xrange = xrange;
00107 };
00108 public:
00109 TargetPixelSelector_Valid ( NullParamType npt = nullParam ) :w(0xffffff),h(0xffffff),xrange(1)
00110 {}
00111 ;
00112 };
00113
00114
00115
00116
00117
00118
00119
00120 template<int pixelsize>
00121 class SourcePixelSelector_Plain
00122 {
00123 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00124 const PixelType* pointer;
00125 int pitch;
00126 int linelength;
00127 const Surface* surface;
00128 protected:
00129 SourcePixelSelector_Plain() : pointer(NULL), surface(NULL)
00130 {}
00131 ;
00132
00133 void init ( const Surface& srv )
00134 {
00135 surface = &srv;
00136 pointer = (const PixelType*)(srv.pixels());
00137 linelength = srv.pitch()/sizeof(PixelType);
00138 pitch = linelength - srv.w();
00139 };
00140
00141 PixelType getPixel(int x, int y)
00142 {
00143 if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
00144 return surface->GetPixel(SPoint(x,y));
00145 else
00146 return surface->GetPixelFormat().colorkey();
00147 };
00148
00149 PixelType nextPixel()
00150 {
00151 return *(pointer++);
00152 };
00153 void nextLine()
00154 {
00155 pointer += pitch;
00156 };
00157 void skipPixels( int pixNum )
00158 {
00159 pointer += pixNum;
00160 };
00161
00162 int getSourcePixelSkip()
00163 {
00164 return 0;
00165 };
00166
00167 void skipWholeLine()
00168 {
00169 pointer += linelength;
00170 };
00171
00172 int getWidth()
00173 {
00174 return surface->w();
00175 };
00176 int getHeight()
00177 {
00178 return surface->h();
00179 };
00180 public:
00181 SourcePixelSelector_Plain ( NullParamType npt )
00182 {}
00183 ;
00184 };
00185
00186
00187 template<
00188 int BytesPerSourcePixel,
00189 int BytesPerTargetPixel
00190 >
00191 class ColorConverter
00192 {
00193 public:
00194 typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType SourcePixelType;
00195 typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType TargetPixelType;
00196 private:
00197 SourcePixelType srcColorKey;
00198 TargetPixelType destColorKey;
00199 public:
00200 ColorConverter( const Surface& sourceSurface, Surface& targetSurface )
00201 {}
00202 ;
00203 TargetPixelType convert ( SourcePixelType sp )
00204 {
00205 return sp;
00206 };
00207 };
00208
00209
00210 template<>
00211 class ColorConverter<4,1>
00212 {
00213 int rshift, gshift, bshift;
00214 public:
00215 typedef PixelSize2Type<4>::PixelType SourcePixelType;
00216 typedef PixelSize2Type<1>::PixelType TargetPixelType;
00217 private:
00218 SourcePixelType srcColorKey;
00219 TargetPixelType destColorKey;
00220 bool srcHasColorKey;
00221 int srcColorMask;
00222 public:
00223
00224 ColorConverter( const Surface& sourceSurface, Surface& targetSurface )
00225 {
00226 rshift = sourceSurface.GetPixelFormat().Rshift() + 2;
00227 gshift = sourceSurface.GetPixelFormat().Gshift() + 2;
00228 bshift = sourceSurface.GetPixelFormat().Bshift() + 2;
00229 srcColorMask = ~sourceSurface.GetPixelFormat().Amask();
00230 srcColorKey = sourceSurface.GetPixelFormat().colorkey() & srcColorMask;
00231
00232 srcHasColorKey = sourceSurface.flags() & SDL_SRCCOLORKEY;
00233 if ( targetSurface.flags() & SDL_SRCCOLORKEY )
00234 destColorKey = targetSurface.GetPixelFormat().colorkey();
00235 else
00236 destColorKey = 0xff;
00237
00238
00239 };
00240 TargetPixelType convert ( SourcePixelType sp )
00241 {
00242 #ifdef use_truecolor2pal
00243 if ( srcHasColorKey && (sp & srcColorMask) == srcColorKey )
00244 return destColorKey;
00245 else
00246 return truecolor2pal_table[ ((sp >> rshift) & 0x3f) + (((sp >> gshift) & 0x3f) << 6) + (((sp >> bshift) & 0x3f) << 12)];
00247 #else
00248 return destColorKey;
00249 #endif
00250 };
00251 };
00252
00253 template<>
00254 class ColorConverter<1,4>
00255 {
00256 public:
00257 typedef PixelSize2Type<1>::PixelType SourcePixelType;
00258 typedef PixelSize2Type<4>::PixelType TargetPixelType;
00259 private:
00260 SDL_Color* palette;
00261 int rshift, gshift, bshift,ashift;
00262 bool hasColorKey;
00263 TargetPixelType colorKey;
00264 public:
00265
00266 ColorConverter( const Surface& sourceSurface, Surface& targetSurface )
00267 {
00268 if ( targetSurface.flags() & SDL_SRCCOLORKEY ) {
00269 hasColorKey = true;
00270 colorKey = targetSurface.GetPixelFormat().colorkey();
00271 } else {
00272 hasColorKey = false;
00273 colorKey = 0;
00274 }
00275
00276 palette = sourceSurface.GetPixelFormat().palette()->colors;
00277 rshift = targetSurface.GetPixelFormat().Rshift();
00278 gshift = targetSurface.GetPixelFormat().Gshift();
00279 bshift = targetSurface.GetPixelFormat().Bshift();
00280 if ( targetSurface.GetPixelFormat().Amask() )
00281 ashift = targetSurface.GetPixelFormat().Ashift();
00282 else
00283 ashift = firstBit( ~( targetSurface.GetPixelFormat().Rmask() | targetSurface.GetPixelFormat().Gmask() | targetSurface.GetPixelFormat().Bmask()));
00284
00285 };
00286
00287 TargetPixelType convert ( SourcePixelType sp )
00288 {
00289 if ( sp == 0xff ) {
00290 if ( hasColorKey )
00291 return colorKey;
00292 else
00293 return Surface::transparent << ashift;
00294 } else {
00295 TargetPixelType a = Surface::opaque;
00296 a <<= ashift;
00297 return TargetPixelType(palette[sp].r << rshift) + TargetPixelType(palette[sp].g << gshift) + TargetPixelType(palette[sp].b << bshift) + a;
00298 }
00299 };
00300
00301 };
00302
00303
00304
00305 template<
00306 int BytesPerSourcePixel,
00307 int BytesPerTargetPixel,
00308 template<int> class SourceColorTransform,
00309 template<int> class ColorMerger,
00310 template<int> class SourcePixelSelector = SourcePixelSelector_Plain,
00311 class TargetPixelSelector = TargetPixelSelector_All,
00312 template<int,int> class MyColorConverter = ColorConverter
00313 >
00314 class MegaBlitter : public SourceColorTransform<BytesPerSourcePixel>,
00315 public ColorMerger<BytesPerTargetPixel>,
00316 public SourcePixelSelector<BytesPerSourcePixel>,
00317 public TargetPixelSelector
00318 {
00319 typedef typename PixelSize2Type<BytesPerSourcePixel>::PixelType SourcePixelType;
00320 typedef typename PixelSize2Type<BytesPerTargetPixel>::PixelType TargetPixelType;
00321 public:
00322 MegaBlitter()
00323 { }
00324 ;
00325 MegaBlitter( const SourceColorTransform<BytesPerSourcePixel>& scm, const ColorMerger<BytesPerTargetPixel>& cm, const SourcePixelSelector<BytesPerSourcePixel>& sps, const TargetPixelSelector& tps ) :
00326 SourceColorTransform<BytesPerSourcePixel>( scm ),
00327 ColorMerger<BytesPerTargetPixel>( cm ),
00328 SourcePixelSelector<BytesPerSourcePixel>( sps ),
00329 TargetPixelSelector( tps )
00330 { }
00331 ;
00332
00333 int getWidth()
00334 {
00335 return SourcePixelSelector<BytesPerTargetPixel>::getWidth();
00336 };
00337 int getHeight()
00338 {
00339 return SourcePixelSelector<BytesPerTargetPixel>::getHeight();
00340 };
00341
00342 void initSource( const Surface& src )
00343 {
00344 SourcePixelSelector<BytesPerSourcePixel>::init( src );
00345 }
00346
00347
00348 void blit( const Surface& src, Surface& dst, SPoint dstPos )
00349 {
00350 assert( src.GetPixelFormat().BytesPerPixel() == BytesPerSourcePixel );
00351 assert( dst.GetPixelFormat().BytesPerPixel() == BytesPerTargetPixel );
00352
00353 SurfaceLock sl( dst );
00354
00355 ColorMerger<BytesPerTargetPixel>::init( BytesPerSourcePixel == BytesPerTargetPixel ? src : dst );
00356 SourcePixelSelector<BytesPerSourcePixel>::init( src );
00357
00358 MyColorConverter<BytesPerSourcePixel,BytesPerTargetPixel> colorConverter( src, dst );
00359
00360 SourceColorTransform<BytesPerSourcePixel>::init( src );
00361
00362 int h = SourcePixelSelector<BytesPerSourcePixel>::getHeight();
00363 int w = SourcePixelSelector<BytesPerSourcePixel>::getWidth();
00364
00365 TargetPixelSelector::init( dst, dstPos, w, h );
00366
00367 TargetPixelType* pix = (TargetPixelType*)( dst.pixels() );
00368
00369 pix += dstPos.y * dst.pitch()/BytesPerTargetPixel + dstPos.x;
00370
00371 int pitch = dst.pitch()/BytesPerTargetPixel - w;
00372
00373 typedef SourcePixelSelector<BytesPerTargetPixel> SPS;
00374 for ( int y = 0; y < h; ++y ) {
00375 for ( int x = 0; x < w; ++x ) {
00376 int s = TargetPixelSelector::skipTarget(x,y);
00377 if ( s >= 0 && SourcePixelSelector<BytesPerSourcePixel>::getSourcePixelSkip() > s )
00378 s = SourcePixelSelector<BytesPerSourcePixel>::getSourcePixelSkip();
00379
00380 if ( s==0 ) {
00381 ColorMerger<BytesPerTargetPixel>::assign ( colorConverter.convert( SourceColorTransform<BytesPerSourcePixel>::transform( SourcePixelSelector<BytesPerSourcePixel>::nextPixel())), pix );
00382 ++pix;
00383 } else {
00384 if ( s > 0 ) {
00385 SourcePixelSelector<BytesPerSourcePixel>::skipPixels( s );
00386 pix += s;
00387 x += s - 1 ;
00388 } else
00389 return;
00390 }
00391 }
00392 SourcePixelSelector<BytesPerSourcePixel>::nextLine();
00393 pix += pitch;
00394 }
00395 };
00396
00397 };
00398
00399
00400 template<
00401 template<int> class SourceColorTransform,
00402 template<int> class ColorMerger,
00403 template<int> class SourcePixelSelector,
00404 class TargetPixelSelector,
00405 typename SourceColorTransformParameter,
00406 typename ColorMergerParameter,
00407 typename SourcePixelSelectorParameter,
00408 typename TargetPixelSelectorParameter
00409 >
00410 void megaBlitter ( const Surface& src,
00411 Surface& dst,
00412 const SPoint& pos,
00413 const SourceColorTransformParameter& scmp = nullParam,
00414 const ColorMergerParameter& cmp = nullParam,
00415 const SourcePixelSelectorParameter spsp = nullParam,
00416 const TargetPixelSelectorParameter tpsp = nullParam )
00417 {
00418 switch ( src.GetPixelFormat().BytesPerPixel() ) {
00419 case 1: {
00420 switch ( dst.GetPixelFormat().BytesPerPixel() ) {
00421 case 1: {
00422 MegaBlitter<
00423 1,1,
00424 SourceColorTransform,
00425 ColorMerger,
00426 SourcePixelSelector,
00427 TargetPixelSelector
00428 > blitter (
00429 (SourceColorTransform<1>)( scmp ),
00430 (ColorMerger<1>)( cmp ),
00431 (SourcePixelSelector<1>)( spsp ),
00432 TargetPixelSelector(tpsp)
00433 );
00434 blitter.blit( src, dst, pos );
00435 }
00436 break;
00437 case 3:
00438 case 4: {
00439 MegaBlitter<
00440 1,4,
00441 SourceColorTransform,
00442 ColorMerger,
00443 SourcePixelSelector,
00444 TargetPixelSelector
00445 > blitter (
00446 (SourceColorTransform<1>)( scmp ),
00447 (ColorMerger<4>)( cmp ),
00448 (SourcePixelSelector<1>)( spsp ),
00449 TargetPixelSelector(tpsp)
00450 );
00451 blitter.blit( src, dst, pos );
00452 }
00453 break;
00454 };
00455 }
00456 break;
00457 case 3:
00458 case 4: {
00459 switch ( dst.GetPixelFormat().BytesPerPixel() ) {
00460 case 1: {
00461 MegaBlitter<
00462 4,1,
00463 SourceColorTransform,
00464 ColorMerger,
00465 SourcePixelSelector,
00466 TargetPixelSelector
00467 > blitter (
00468 (SourceColorTransform<4>)( scmp ),
00469 (ColorMerger<1>)( cmp ),
00470 (SourcePixelSelector<4>)( spsp ),
00471 TargetPixelSelector(tpsp)
00472 );
00473 blitter.blit( src, dst, pos );
00474 }
00475 break;
00476 case 3:
00477 case 4: {
00478 MegaBlitter<
00479 4,4,
00480 SourceColorTransform,
00481 ColorMerger,
00482 SourcePixelSelector,
00483 TargetPixelSelector
00484 > blitter (
00485 (SourceColorTransform<4>)( scmp ),
00486 (ColorMerger<4>)( cmp ),
00487 (SourcePixelSelector<4>)( spsp ),
00488 TargetPixelSelector(tpsp)
00489 );
00490 blitter.blit( src, dst, pos );
00491 }
00492 break;
00493 };
00494 }
00495 break;
00496 }
00497 }
00498
00499
00500
00502
00503 class Player;
00504
00505
00506 template<int pixelsize>
00507 class ColorTransform_None
00508 {
00509 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00510 protected:
00511 ColorTransform_None()
00512 {}
00513 ;
00514 PixelType transform( PixelType col)
00515 {
00516 return col;
00517 };
00518 void init( const Surface& src )
00519 {}
00520 ;
00521 public:
00522 ColorTransform_None ( NullParamType npt )
00523 {}
00524 ;
00525 };
00526
00527
00528
00529
00530 template<int pixelSize>
00531 class ColorTransform_XLAT
00532 {
00533 const char* table;
00534
00535 protected:
00536 ColorTransform_XLAT() : table(NULL)
00537 {}
00538 ;
00539
00540 void init( const Surface& src )
00541 {}
00542 ;
00543
00544 Color transform( Color col)
00545 {
00546 if ( table )
00547 return table[col];
00548 else
00549 return col;
00550 };
00551
00552 public:
00553 void setTranslationTable( const char* translationTable )
00554 {
00555 table = translationTable;
00556 };
00557
00558 ColorTransform_XLAT ( NullParamType npt ) : table(NULL)
00559 {}
00560 ;
00561
00562 ColorTransform_XLAT ( const char* t ) : table ( t )
00563 {}
00564 ;
00565 };
00566
00567
00568 template<int pixelSize>
00569 class ColorTransform_Gray
00570 { }
00571 ;
00572
00573
00574 template<>
00575 class ColorTransform_Gray<4>
00576 {
00577 protected:
00578 ColorTransform_Gray()
00579 {}
00580 ;
00581
00582 Color transform( Color col)
00583 {
00584 int i = ((col & 0xff) + ((col >> 8) & 0xff) + ((col >> 16) & 0xff)) / 3;
00585 return i + (i<<8) + (i <<16) + (col & 0xff000000);
00586 };
00587
00588 void init( const Surface& src )
00589 {}
00590 ;
00591
00592 public:
00593 ColorTransform_Gray ( NullParamType npt )
00594 {}
00595 ;
00596 };
00597
00598
00600
00601 template<int pixelsize>
00602 class ColorMerger_PlainOverwrite
00603 {
00604 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00605 protected:
00606 ColorMerger_PlainOverwrite()
00607 {}
00608 ;
00609 void init( const Surface& dst )
00610 {}
00611 ;
00612 void assign ( PixelType src, PixelType* dest )
00613 {
00614 *dest = src;
00615 };
00616 public:
00617 ColorMerger_PlainOverwrite ( NullParamType npt )
00618 {}
00619 ;
00620 };
00621
00622 template<int pixelsize>
00623 class ColorMerger_ColoredOverwrite
00624 {
00625 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00626 DI_Color col;
00627 mutable PixelType transformedColor;
00628 public:
00629 void init( const Surface& dst ) const
00630 {
00631 transformedColor = dst.GetPixelFormat().MapRGB( col );
00632 };
00633 void assign ( PixelType src, PixelType* dest ) const
00634 {
00635 *dest = src;
00636 };
00637 void assign ( PixelType* dest ) const
00638 {
00639 *dest = transformedColor;
00640 };
00641 ColorMerger_ColoredOverwrite ( DI_Color color ) : col(color)
00642 {}
00643 ;
00644 };
00645
00646
00647 template<int pixelsize>
00648 class ColorMerger_AlphaHandler
00649 {
00650 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00651 int colorKey;
00652 int mask;
00653 protected:
00654 ColorMerger_AlphaHandler() : mask ( -1 )
00655 {}
00656 ;
00657
00658 void init( const Surface& srf )
00659 {
00660 if ( srf.flags() & SDL_SRCCOLORKEY ) {
00661 colorKey = srf.GetPixelFormat().colorkey();
00662 if ( pixelsize > 1 )
00663 mask = srf.GetPixelFormat().Rmask() | srf.GetPixelFormat().Gmask() | srf.GetPixelFormat().Bmask();
00664 } else
00665 if ( pixelsize == 1 )
00666 colorKey = 0xff;
00667 else
00668 colorKey = 0xfefefe00;
00669 };
00670
00671 bool isOpaque( PixelType src )
00672 {
00673 return (src & mask ) != colorKey;
00674 }
00675 };
00676
00677
00678 template<>
00679 class ColorMerger_AlphaHandler<1>
00680 {
00681 typedef PixelSize2Type<1>::PixelType PixelType;
00682 int colorKey;
00683 int mask;
00684 protected:
00685 ColorMerger_AlphaHandler() : mask ( -1 )
00686 {}
00687 ;
00688
00689 void init( const Surface& srf )
00690 {
00691 if ( srf.flags() & SDL_SRCCOLORKEY ) {
00692 colorKey = srf.GetPixelFormat().colorkey();
00693 } else
00694 colorKey = 0xff;
00695 };
00696
00697 bool isOpaque( PixelType src )
00698 {
00699 return (src & mask ) != colorKey;
00700 }
00701 };
00702
00703 template<>
00704 class ColorMerger_AlphaHandler<4>
00705 {
00706 typedef PixelSize2Type<4>::PixelType PixelType;
00707 protected:
00708 int amask, ashift;
00709 PixelType colorKey;
00710 bool hasColorKey;
00711 int ckmask;
00712 protected:
00713 ColorMerger_AlphaHandler() : amask ( -1 ), ashift(0), colorKey(0), hasColorKey(false), ckmask(0)
00714 {}
00715 ;
00716
00717 void init( const Surface& srf )
00718 {
00719 if ( srf.flags() & SDL_SRCCOLORKEY ) {
00720 hasColorKey = true;
00721 colorKey = srf.GetPixelFormat().colorkey();
00722 ckmask = srf.GetPixelFormat().Rmask() | srf.GetPixelFormat().Gmask() | srf.GetPixelFormat().Bmask();
00723 } else {
00724 if ( srf.GetPixelFormat().Amask() ) {
00725 amask = srf.GetPixelFormat().Amask();
00726 ashift = srf.GetPixelFormat().Ashift();
00727 } else {
00728 amask = ~( srf.GetPixelFormat().Rmask() | srf.GetPixelFormat().Gmask() | srf.GetPixelFormat().Bmask() );
00729 ashift = firstBit(amask);
00730 }
00731 }
00732 };
00733
00734 bool isOpaque( PixelType src )
00735 {
00736 if ( hasColorKey )
00737 return (src & ckmask) != colorKey;
00738 else
00739 return PixelType((src & amask ) >> ashift) >= 128;
00740 };
00741 };
00742
00743
00744 template<int pixelsize>
00745 class ColorMerger_AlphaOverwrite : public ColorMerger_AlphaHandler<pixelsize>
00746 {
00747 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00748 protected:
00749
00750 void assign ( PixelType src, PixelType* dest )
00751 {
00752 if ( isOpaque(src ) ) {
00753 *dest = src;
00754 }
00755 };
00756
00757 public:
00758 ColorMerger_AlphaOverwrite( NullParamType npt = nullParam )
00759 {}
00760 ;
00761 };
00762
00763
00764 template<int pixelsize>
00765 class ColorMerger_AlphaMerge : public ColorMerger_AlphaHandler<pixelsize>
00766 {
00767 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00768 protected:
00769
00770 void assign ( PixelType src, PixelType* dest )
00771 {
00772 if ( isOpaque(src ) ) {
00773 *dest = src;
00774 }
00775 };
00776
00777 public:
00778 ColorMerger_AlphaMerge( NullParamType npt = nullParam )
00779 {}
00780 ;
00781 };
00782
00783 template<>
00784 class ColorMerger_AlphaMerge<4> : public ColorMerger_AlphaHandler<4>
00785 {
00786 typedef PixelSize2Type<4>::PixelType PixelType;
00787 protected:
00788
00789 void assign ( PixelType src, PixelType* dest )
00790 {
00791 if ( hasColorKey ) {
00792 if ( (src & ckmask) != colorKey )
00793 *dest = src;
00794 } else {
00795 PixelType alpha = PixelType((src & amask ) >> ashift);
00796 if ( alpha == PixelType(Surface::opaque))
00797 *dest = src;
00798 else
00799 if ( alpha != PixelType(Surface::transparent)) {
00800
00801
00802
00803
00804
00805
00806 PixelType d = *dest;
00807 PixelType dalpha = d & 0xff000000;
00808 PixelType s1 = src & 0xff00ff;
00809 PixelType d1 = d & 0xff00ff;
00810 d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
00811 src &= 0xff00;
00812 d &= 0xff00;
00813 d = (d + ((src - d) * alpha >> 8)) & 0xff00;
00814 *dest = d1 | d | dalpha;
00815 }
00816
00817 }
00818 };
00819
00820 public:
00821 ColorMerger_AlphaMerge( NullParamType npt = nullParam )
00822 {}
00823 ;
00824 };
00825
00826
00827
00828
00829 template<int pixelsize>
00830 class ColorMerger_AlphaShadow
00831 {}
00832 ;
00833
00834
00835 template<>
00836 class ColorMerger_AlphaShadow<1> : public ColorMerger_AlphaHandler<1>
00837 {
00838 typedef PixelSize2Type<1>::PixelType PixelType;
00839 const char* table;
00840 protected:
00841
00842 void assign ( PixelType src, PixelType* dest )
00843 {
00844
00845 if ( isOpaque(src ) ) {
00846 *dest = table[*dest];
00847 }
00848 };
00849 public:
00850 ColorMerger_AlphaShadow ( NullParamType npt = nullParam) : table ( xlattables.a.dark1 )
00851 {}
00852 ;
00853 ColorMerger_AlphaShadow ( const char* translationTable ) : table ( translationTable )
00854 {}
00855 ;
00856 };
00857
00858 template<>
00859 class ColorMerger_AlphaShadow<4> : public ColorMerger_AlphaHandler<4>
00860 {
00861 typedef PixelSize2Type<4>::PixelType PixelType;
00862 protected:
00863
00864 void init( const Surface& srf )
00865 {
00866 ColorMerger_AlphaHandler<4>::init(srf);
00867 };
00868
00869
00870 void assign ( PixelType src, PixelType* dest )
00871 {
00872 if ( isOpaque(src ) ) {
00873 *dest = ((*dest >> 1) & 0x7f7f7f7f) | (*dest & 0xff000000 );
00874 }
00875 };
00876 public:
00877 ColorMerger_AlphaShadow ( NullParamType npt = nullParam)
00878 {}
00879 ;
00880 ColorMerger_AlphaShadow ( const char* translationTable )
00881 {}
00882 ;
00883 };
00884
00885
00886
00887 template<int pixelsize>
00888 class ColorMerger_AlphaMixer
00889 {}
00890 ;
00891
00892
00893 template<>
00894 class ColorMerger_AlphaMixer<1> : public ColorMerger_AlphaHandler<1>
00895 {
00896 typedef PixelSize2Type<1>::PixelType PixelType;
00897 protected:
00898 void assign ( PixelType src, PixelType* dest )
00899 {
00900 if ( isOpaque(src ) )
00901 *dest = colormixbufchar[*dest + src*256 ];
00902 };
00903 public:
00904 ColorMerger_AlphaMixer ( NullParamType npt = nullParam )
00905 {}
00906 ;
00907 };
00908
00909 template<>
00910 class ColorMerger_AlphaMixer<4> : public ColorMerger_AlphaHandler<4>
00911 {
00912 typedef PixelSize2Type<4>::PixelType PixelType;
00913 protected:
00914 void assign ( PixelType src, PixelType* dest )
00915 {
00916
00917 if ( isOpaque(src ) ) {
00918 *dest = ((*dest >> 1) & 0x7f7f7f7f) + ((src >> 1) & 0x7f7f7f7f);
00919 }
00920 };
00921 public:
00922 ColorMerger_AlphaMixer ( NullParamType npt = nullParam )
00923 {}
00924 ;
00925 };
00926
00927
00928
00929 extern const int ColorMerger_Alpha_XLAT_Table_shadings[8];
00930
00931 template<int pixelsize>
00932 class ColorMerger_Alpha_XLAT_TableShifter : public ColorMerger_AlphaHandler<pixelsize>
00933 {
00934 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00935 const char* table;
00936 protected:
00937 void assign ( PixelType src, PixelType* dest )
00938 {
00939 if ( src == 0 || src >= 8 )
00940 return;
00941
00942 *dest = lighten_Color( *dest, ColorMerger_Alpha_XLAT_Table_shadings[src] );
00943
00944
00945
00946
00947
00948
00949 };
00950
00951 public:
00952 void setNeutralTranslationTable( const char* translationTable )
00953 {
00954 table = translationTable;
00955 };
00956
00957 ColorMerger_Alpha_XLAT_TableShifter( NullParamType npt = nullParam ) : table ( NULL )
00958 {}
00959 ;
00960 ColorMerger_Alpha_XLAT_TableShifter ( const char* translationTable ) : table ( translationTable )
00961 {}
00962 ;
00963 };
00964
00965 template<>
00966 class ColorMerger_Alpha_XLAT_TableShifter<1> : public ColorMerger_AlphaHandler<1>
00967 {
00968 typedef PixelSize2Type<1>::PixelType PixelType;
00969 const char* table;
00970 protected:
00971 void assign ( PixelType src, PixelType* dest )
00972 {
00973
00974 if ( isOpaque(src ) ) {
00975 *dest = table[ *dest + src*256 ];
00976 }
00977 };
00978
00979 public:
00980 void setNeutralTranslationTable( const char* translationTable )
00981 {
00982 table = translationTable;
00983 };
00984
00985 ColorMerger_Alpha_XLAT_TableShifter( NullParamType npt = nullParam ) : table ( NULL )
00986 {}
00987 ;
00988 ColorMerger_Alpha_XLAT_TableShifter ( const char* translationTable ) : table ( translationTable )
00989 {}
00990 ;
00991 };
00992
00993
00994 template<int pixelsize>
00995 class ColorMerger_Brightness
00996 {
00997 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00998 float b;
00999 public:
01000
01001 void assign ( PixelType src, PixelType* dest ) const
01002 {
01003 PixelType d = 0;
01004 for ( int i = 0; i < 3; ++i)
01005 d |= min( max( int( float(((*dest) >> (i*8)) & 0xff) * b ), 0 ), 255) << (i*8);
01006 d |= (*dest & 0xff000000);
01007
01008 *dest = d;
01009 };
01010
01011 ColorMerger_Brightness( float brightness )
01012 {
01013 b = brightness;
01014 };
01015 };
01016
01017
01018 template<int pixelsize>
01019 class ColorMerger_Set
01020 {
01021 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01022 SDLmm::Color col;
01023 public:
01024
01025 void assign ( PixelType src, PixelType* dest ) const
01026 {
01027 *dest = col;
01028 };
01029
01030
01031 ColorMerger_Set( SDLmm::Color color )
01032 {
01033 col = color;
01034 };
01035 };
01036
01037
01039
01040
01041
01042 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01043 class SourcePixelSelector_Rotation: public SourcePixelSelector
01044 {
01045 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01046 int degrees;
01047 int x,y;
01048 int w,h;
01049 protected:
01050
01051 void init ( const Surface& srv )
01052 {
01053 SourcePixelSelector::init(srv);
01054 w = SourcePixelSelector::getWidth();
01055 h = SourcePixelSelector::getHeight();
01056 };
01057
01058
01059 PixelType getPixel(int x, int y)
01060 {
01061 SPoint newpos = ::getPixelRotationLocation( SPoint(x,y), w, h, degrees );
01062 return SourcePixelSelector::getPixel ( newpos.x, newpos.y );
01063 };
01064
01065 PixelType nextPixel()
01066 {
01067 return getPixel(x++, y);
01068 };
01069
01070 void skipPixels( int pixNum )
01071 {
01072 x += pixNum;
01073 };
01074
01075 int getSourcePixelSkip()
01076 {
01077 return 0;
01078 };
01079
01080 void nextLine()
01081 {
01082 x = 0;
01083 y +=1;
01084 };
01085
01086 public:
01087 void setAngle( int degrees )
01088 {
01089 this->degrees = degrees;
01090 };
01091
01092 SourcePixelSelector_Rotation( NullParamType npt = nullParam ) : degrees(0),x(0),y(0),w(0),h(0)
01093 {}
01094
01095 SourcePixelSelector_Rotation( int degreesToRotate ) : degrees(degreesToRotate),x(0),y(0),w(0),h(0)
01096 {}
01097 };
01098
01099 template<int pixelsize>
01100 class SourcePixelSelector_DirectRotation: public SourcePixelSelector_Rotation<pixelsize>
01101 {
01102 public:
01103 SourcePixelSelector_DirectRotation( NullParamType npt = nullParam )
01104 {}
01105 SourcePixelSelector_DirectRotation( int degreesToRotate ) : SourcePixelSelector_Rotation<pixelsize>(degreesToRotate)
01106 {}
01107 }
01108 ;
01109
01110
01111
01112 class RotationCache
01113 {
01114 protected:
01115 static map<int,int*> cache;
01116 static int xsize;
01117 static int ysize;
01118 };
01119
01120 template<int pixelsize>
01121 class SourcePixelSelector_CacheRotation : public RotationCache
01122 {
01123 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01124 const Surface* surface;
01125 int degrees;
01126 bool useCache;
01127 const PixelType* pixelStart;
01128 const PixelType* currentPixel;
01129 int tableIndex;
01130 int pitch;
01131 int* cacheIndex;
01132 int x,y,w,h;
01133 protected:
01134
01135 void init ( const Surface& srv )
01136 {
01137 if ( !surface ) {
01138 surface = &srv;
01139 } else {
01140 assert ( surface == &srv );
01141 }
01142 tableIndex = 0;
01143 pixelStart = currentPixel = (PixelType*)surface->pixels();
01144 pitch = srv.pitch()/sizeof(PixelType) - srv.w();
01145 w = srv.w();
01146 h = srv.h();
01147 }
01148
01149 PixelType nextPixel()
01150 {
01151 if ( useCache && degrees != 0 ) {
01152 ++currentPixel;
01153
01154 assert ( cacheIndex );
01155 int index = cacheIndex[tableIndex++];
01156 if ( index >= 0 )
01157 return pixelStart[index];
01158 else
01159 return surface->GetPixelFormat().colorkey();
01160 } else {
01161 if ( degrees == 0 ) {
01162 ++tableIndex;
01163 return *(currentPixel++);
01164 } else {
01165 SPoint newpos = ::getPixelRotationLocation( SPoint(x++,y), w, h, degrees );
01166 return getSourcePixel ( newpos.x, newpos.y );
01167 }
01168 }
01169 };
01170
01171 void skipPixels( int pixNum )
01172 {
01173 currentPixel += pixNum;
01174 tableIndex += pixNum;
01175 x += pixNum;
01176 };
01177
01178 int getSourcePixelSkip()
01179 {
01180 return 0;
01181 };
01182
01183 void nextLine()
01184 {
01185 currentPixel += pitch;
01186 ++y;
01187 x = 0;
01188 };
01189
01190 int getWidth()
01191 {
01192 return surface->w();
01193 };
01194 int getHeight()
01195 {
01196 return surface->h();
01197 };
01198
01199 private:
01200 PixelType getSourcePixel(int x, int y)
01201 {
01202 if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
01203 return surface->GetPixel(SPoint(x,y));
01204 else
01205 return surface->GetPixelFormat().colorkey();
01206 };
01207
01208
01209 public:
01210 void setAngle( const Surface& srv, int degrees )
01211 {
01212 init ( srv );
01213
01214 if ( xsize == -1 ) {
01215 xsize = surface->w();
01216 ysize = surface->h();
01217 }
01218
01219 this->degrees = degrees;
01220 if ( degrees != 0 && surface->w() == xsize && surface->h() == ysize ) {
01221 useCache = true;
01222 if ( cache.find( degrees ) == cache.end() ) {
01223 int* index = new int[surface->w() * surface->h()];
01224 cache[degrees] = index;
01225 for ( int y = 0; y < surface->h(); ++y )
01226 for ( int x = 0; x < surface->w(); ++x ) {
01227 SPoint pnt = getPixelRotationLocation( SPoint(x,y), surface->w(),surface->h(), degrees );
01228 if ( pnt.x >= 0 && pnt.y >= 0 && pnt.x < surface->w() && pnt.y < surface->h() )
01229 *index++ = pnt.x + pnt.y * surface->pitch()/pixelsize;
01230 else
01231 *index++ = -1;
01232 }
01233 }
01234 cacheIndex = cache[degrees];
01235 }
01236 }
01237
01238 SourcePixelSelector_CacheRotation( NullParamType npt = nullParam ) : surface(NULL), degrees(0), useCache(false),pixelStart(NULL), currentPixel(NULL),tableIndex(0),pitch(0), cacheIndex(NULL),x(0),y(0),w(0),h(0)
01239 {}
01240 ;
01241
01242 SourcePixelSelector_CacheRotation( const Surface& srv, int degrees ) : surface(NULL), degrees(0), useCache(false),pixelStart(NULL), currentPixel(NULL),tableIndex(0),pitch(0), cacheIndex(NULL),x(0),y(0),w(0),h(0)
01243 {
01244 setAngle ( srv, degrees );
01245 };
01246
01247 SourcePixelSelector_CacheRotation( pair<const Surface*, int> p ) : surface(NULL), degrees(0), useCache(false),pixelStart(NULL), currentPixel(NULL),tableIndex(0),pitch(0), cacheIndex(NULL),x(0),y(0),w(0),h(0)
01248 {
01249 setAngle ( *(p.first), p.second );
01250 };
01251
01252
01253 };
01254
01255
01256 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01257 class SourcePixelSelector_Zoom: public SourcePixelSelector
01258 {
01259 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01260 float zoomFactorX;
01261 float zoomFactorY;
01262 int x,y;
01263 protected:
01264
01265 int getWidth()
01266 {
01267 return int( zoomFactorX * SourcePixelSelector::getWidth() );
01268 };
01269 int getHeight()
01270 {
01271 return int( zoomFactorY * SourcePixelSelector::getHeight() );
01272 };
01273
01274 PixelType getPixel(int x, int y)
01275 {
01276 return SourcePixelSelector::getPixel( int(float(x) / zoomFactorX), int(float(y) / zoomFactorY));
01277 };
01278
01279 PixelType nextPixel()
01280 {
01281 return getPixel(x++, y);
01282 };
01283
01284 void skipPixels( int pixNum )
01285 {
01286 x += pixNum;
01287 };
01288
01289 int getSourcePixelSkip()
01290 {
01291 return 0;
01292 };
01293
01294 void nextLine()
01295 {
01296 x= 0;
01297 ++y;
01298 };
01299
01300 public:
01301 void setZoom( float factor )
01302 {
01303 this->zoomFactorX = factor;
01304 this->zoomFactorY = factor;
01305 };
01306 void setZoom( float factorX, float factorY )
01307 {
01308 this->zoomFactorX = factorX;
01309 this->zoomFactorY = factorY;
01310 };
01311
01312 float getZoomX()
01313 {
01314 return zoomFactorX;
01315 };
01316 float getZoomY()
01317 {
01318 return zoomFactorY;
01319 };
01320
01321 void setSize( int sourceWidth, int sourceHeight, int targetWidth, int targetHeight, bool forceSquare = true )
01322 {
01323 float zw = float(targetWidth) / float(sourceWidth);
01324 float zh = float(targetHeight)/ float(sourceHeight);
01325 if ( forceSquare )
01326 setZoom( min ( zw,zh));
01327 else
01328 setZoom( zw,zh );
01329 };
01330
01331 SourcePixelSelector_Zoom( NullParamType npt = nullParam) : zoomFactorX(1),zoomFactorY(1),x(0),y(0)
01332 {}
01333 ;
01334
01335 };
01336
01337 template<int pixelsize>
01338 class SourcePixelSelector_DirectZoom: public SourcePixelSelector_Zoom<pixelsize>
01339 {
01340 public:
01341 SourcePixelSelector_DirectZoom( NullParamType npt = nullParam)
01342 {}
01343 ;
01344 };
01345
01346
01347 class ZoomCache
01348 {
01349 protected:
01350 typedef map<float,int*> ZoomMap;
01351 static ZoomMap zoomCache;
01352 };
01353
01354
01355 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01356 class SourcePixelSelector_CacheZoom : private ZoomCache, public SourcePixelSelector
01357 {
01358 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01359 const Surface* surface;
01360 float zoomFactor;
01361
01362 int currSrcX;
01363 int currSrcY;
01364 int* xp;
01365 int* yp;
01366 int offsetx;
01367 int offsety;
01368 ZoomMap::iterator cacheit;
01369 protected:
01370
01371 int getWidth()
01372 {
01373 return int( zoomFactor * SourcePixelSelector::getWidth() );
01374 };
01375 int getHeight()
01376 {
01377 return int( zoomFactor * SourcePixelSelector::getHeight() );
01378 };
01379
01380 PixelType getPixel(int x, int y)
01381 {
01382 return SourcePixelSelector::getPixel( int(float(x) / zoomFactor), int(float(y) / zoomFactor));
01383 };
01384
01385 PixelType nextPixel()
01386 {
01387 for ( int i = 0; i < *xp; ++i )
01388 SourcePixelSelector::nextPixel();
01389 ++xp;
01390
01391 return SourcePixelSelector::nextPixel();
01392 };
01393
01394 void skipPixels( int pixNum )
01395 {
01396 int count = pixNum;
01397 for ( int i = 0; i < pixNum; ++i ) {
01398 count += *xp;
01399 ++xp;
01400 }
01401 SourcePixelSelector::skipPixels( count );
01402 };
01403
01404 int getSourcePixelSkip()
01405 {
01406 int s = SourcePixelSelector::getSourcePixelSkip();
01407 if ( s ) {
01408 s = int(floor( float(s) * zoomFactor )) -2;
01409 if ( s < 1 )
01410 return 1;
01411 else
01412 return s;
01413 } else
01414 return 0;
01415 };
01416
01417
01418 void nextLine()
01419 {
01420 SourcePixelSelector::nextLine();
01421 for ( int i = 0; i < *yp; ++i )
01422 SourcePixelSelector::skipWholeLine();
01423
01424 xp = &cacheit->second[offsetx];
01425 yp++;
01426 };
01427
01428
01429 public:
01430
01431
01432 void setZoomOffset( int x, int y )
01433 {
01434 offsetx = x;
01435 offsety = y;
01436
01437
01438
01439
01440 }
01441
01442
01443 void setZoom( float factor )
01444 {
01445 this->zoomFactor = factor;
01446 assert ( factor > 0 );
01447 assert ( factor <= 1 );
01448
01449 cacheit = zoomCache.find( factor );
01450 if ( cacheit == zoomCache.end() ) {
01451 int size = max ( SDLmm::Display::GetDisplay().w(), SDLmm::Display::GetDisplay().h() );
01452
01453 int* buf = new int[size+1];
01454 buf[0] = 0;
01455
01456 for ( int i = 0; i < size; ++i ) {
01457 int a1 = int( floor( float(i) / zoomFactor ));
01458 int a2 = int( floor( float(i+1) / zoomFactor ));
01459
01460 buf[i+1] = a2 - a1 - 1;
01461 }
01462
01463 zoomCache[zoomFactor] = buf;
01464 cacheit = zoomCache.find( factor );
01465 }
01466 xp = &cacheit->second[offsetx];
01467 yp = &cacheit->second[offsety];
01468 }
01469
01470 SourcePixelSelector_CacheZoom( NullParamType npt = nullParam ) : surface(NULL), zoomFactor(1), xp(NULL), yp(NULL), offsetx(0), offsety(0)
01471 {
01472 cacheit = zoomCache.end();
01473 };
01474
01475 SourcePixelSelector_CacheZoom( float zoom ) : surface(NULL), zoomFactor(1), xp(NULL), yp(NULL), offsetx(0), offsety(0)
01476 {
01477 cacheit = zoomCache.end();
01478 setZoom ( zoom );
01479 };
01480
01481
01482 };
01483
01484
01485
01486
01487 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01488 class SourcePixelSelector_Flip: public SourcePixelSelector
01489 {
01490 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01491 bool hflip;
01492 bool vflip;
01493 int x,y;
01494 int w,h;
01495 protected:
01496
01497 void init ( const Surface& srv )
01498 {
01499 SourcePixelSelector::init(srv);
01500 w = SourcePixelSelector::getWidth()-1;
01501 h = SourcePixelSelector::getHeight()-1;
01502 };
01503
01504
01505
01506 PixelType getPixel(int x, int y)
01507 {
01508 return SourcePixelSelector::getPixel( hflip? w-x : x , vflip ? h-y : y );
01509 };
01510
01511 PixelType nextPixel()
01512 {
01513 return getPixel(x++, y);
01514 };
01515
01516 void skipPixels( int pixNum )
01517 {
01518 x += pixNum;
01519 };
01520
01521 int getSourcePixelSkip()
01522 {
01523 return 0;
01524 };
01525
01526 void nextLine()
01527 {
01528 x= 0;
01529 ++y;
01530 };
01531
01532 public:
01533 void setFlipping( bool horizontal, bool vertical )
01534 {
01535 hflip = horizontal;
01536 vflip = vertical;
01537 };
01538
01539 SourcePixelSelector_Flip( NullParamType npt = nullParam) : hflip(false),vflip(false),x(0),y(0),w(0),h(0)
01540 {}
01541 ;
01542
01543 SourcePixelSelector_Flip( int flip) : hflip(flip&1),vflip(flip&2),x(0),y(0),w(0),h(0)
01544 {}
01545 ;
01546
01547 };
01548
01549 template<int pixelsize>
01550 class SourcePixelSelector_DirectFlip : public SourcePixelSelector_Flip<pixelsize>
01551 {
01552 public:
01553 SourcePixelSelector_DirectFlip( NullParamType npt = nullParam)
01554 {}
01555 ;
01556 SourcePixelSelector_DirectFlip( int flip) : SourcePixelSelector_Flip<pixelsize>(flip)
01557 {}
01558 ;
01559 };
01560
01561
01562 template<int pixelsize>
01563 class SourcePixelSelector_Rectangle: public SourcePixelSelector_Plain<pixelsize>
01564 {
01565 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01566 int x,y,x1,y1;
01567 int w,h;
01568 protected:
01569 SourcePixelSelector_Rectangle() : x(0),y(0),x1(0),y1(0),w(0),h(0)
01570 {}
01571 ;
01572 public:
01573
01574 SourcePixelSelector_Rectangle( const SDLmm::SRect& rect ) : x(0),y(0),x1(0),y1(0),w(0),h(0)
01575 {
01576 setSrcRectangle( rect );
01577 }
01578 protected:
01579
01580 int getWidth()
01581 {
01582 return min(w, SourcePixelSelector_Plain<pixelsize>::getWidth() -x1 );
01583 };
01584 int getHeight()
01585 {
01586 return min(h, SourcePixelSelector_Plain<pixelsize>::getHeight()-y1 );
01587 };
01588
01589
01590 PixelType getPixel(int x, int y)
01591 {
01592 return SourcePixelSelector_Plain<pixelsize>::getPixel( x + x1, y + y1 );
01593 };
01594
01595 PixelType nextPixel()
01596 {
01597 return getPixel(x++, y);
01598 };
01599
01600 void skipWholeLine()
01601 {
01602 ++y;
01603 };
01604
01605 void skipPixels( int pixNum )
01606 {
01607 x += pixNum;
01608 };
01609
01610 int getSourcePixelSkip()
01611 {
01612 return 0;
01613 };
01614
01615 void nextLine()
01616 {
01617 x= 0;
01618 ++y;
01619 };
01620
01621 public:
01622 void setSrcRectangle( SPoint pos, int width, int height )
01623 {
01624 x1 = pos.x;
01625 y1 = pos.y;
01626 w = width;
01627 h = height;
01628 };
01629 void setSrcRectangle( const SDLmm::SRect& rect )
01630 {
01631 x1 = rect.x;
01632 y1 = rect.y;
01633 w = rect.w;
01634 h = rect.h;
01635 };
01636
01637 };
01638
01639 template<int pixelsize>
01640 class SourcePixelSelector_DirectRectangle
01641 {
01642 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01643 int y,x1,y1;
01644 int w,h;
01645
01646 const PixelType* pointer;
01647 const PixelType* startPointer;
01648 int pitch;
01649 int linelength;
01650 const Surface* surface;
01651 protected:
01652 SourcePixelSelector_DirectRectangle() : y(0),x1(0),y1(0),w(0),h(0),pointer(NULL), surface(NULL)
01653 {}
01654 ;
01655
01656 int getWidth()
01657 {
01658 return min(w, surface->w() -x1 );
01659 };
01660 int getHeight()
01661 {
01662 return min(h, surface->h()-y1 );
01663 };
01664
01665
01666 void init ( const Surface& srv )
01667 {
01668 surface = &srv;
01669 startPointer = pointer = (const PixelType*)(srv.pixels());
01670 linelength = srv.pitch()/sizeof(PixelType);
01671 pitch = linelength - w -1 ;
01672 y = y1;
01673 pointer += x1 + y1 * linelength;
01674 };
01675
01676 PixelType getPixel(int x, int y)
01677 {
01678 x += x1;
01679 y += y1;
01680 if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
01681 return surface->GetPixel(SPoint(x,y));
01682 else
01683 return surface->GetPixelFormat().colorkey();
01684 };
01685
01686
01687 PixelType nextPixel()
01688 {
01689 return *(pointer++);
01690 };
01691
01692
01693 void skipWholeLine()
01694 {
01695 pointer += linelength;
01696 ++y;
01697 };
01698
01699 void skipPixels( int pixNum )
01700 {
01701 pointer += pixNum;
01702 };
01703
01704 int