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 "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 = getFirstBit( ~( 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 = getFirstBit(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 ( this->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 ( this->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 if ( dalpha == Surface::transparent ) {
00809 *dest = src;
00810 } else {
00811 PixelType s1 = src & 0xff00ff;
00812 PixelType d1 = d & 0xff00ff;
00813 d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff;
00814 src &= 0xff00;
00815 d &= 0xff00;
00816 d = (d + ((src - d) * alpha >> 8)) & 0xff00;
00817 *dest = d1 | d | dalpha;
00818 }
00819 }
00820
00821 }
00822 };
00823
00824 public:
00825 ColorMerger_AlphaMerge( NullParamType npt = nullParam )
00826 {}
00827 ;
00828 };
00829
00830
00831
00832
00833 template<int pixelsize>
00834 class ColorMerger_AlphaShadow
00835 {}
00836 ;
00837
00838
00839 template<>
00840 class ColorMerger_AlphaShadow<1> : public ColorMerger_AlphaHandler<1>
00841 {
00842 typedef PixelSize2Type<1>::PixelType PixelType;
00843 const char* table;
00844 protected:
00845
00846 void assign ( PixelType src, PixelType* dest )
00847 {
00848
00849 if ( this->isOpaque(src ) ) {
00850 *dest = table[*dest];
00851 }
00852 };
00853 public:
00854 ColorMerger_AlphaShadow ( NullParamType npt = nullParam) : table ( xlattables.a.dark1 )
00855 {}
00856 ;
00857 ColorMerger_AlphaShadow ( const char* translationTable ) : table ( translationTable )
00858 {}
00859 ;
00860 };
00861
00862 template<>
00863 class ColorMerger_AlphaShadow<4> : public ColorMerger_AlphaHandler<4>
00864 {
00865 typedef PixelSize2Type<4>::PixelType PixelType;
00866 protected:
00867
00868 void init( const Surface& srf )
00869 {
00870 ColorMerger_AlphaHandler<4>::init(srf);
00871 };
00872
00873
00874 void assign ( PixelType src, PixelType* dest )
00875 {
00876 if ( this->isOpaque(src ) ) {
00877 *dest = ((*dest >> 1) & 0x7f7f7f7f) | (*dest & 0xff000000 );
00878 }
00879 };
00880 public:
00881 ColorMerger_AlphaShadow ( NullParamType npt = nullParam)
00882 {}
00883 ;
00884 ColorMerger_AlphaShadow ( const char* translationTable )
00885 {}
00886 ;
00887 };
00888
00889
00890
00891 template<int pixelsize>
00892 class ColorMerger_AlphaMixer
00893 {}
00894 ;
00895
00896
00897 template<>
00898 class ColorMerger_AlphaMixer<1> : public ColorMerger_AlphaHandler<1>
00899 {
00900 typedef PixelSize2Type<1>::PixelType PixelType;
00901 protected:
00902 void assign ( PixelType src, PixelType* dest )
00903 {
00904 if ( this->isOpaque(src ) )
00905 *dest = colormixbufchar[*dest + src*256 ];
00906 };
00907 public:
00908 ColorMerger_AlphaMixer ( NullParamType npt = nullParam )
00909 {}
00910 ;
00911 };
00912
00913 template<>
00914 class ColorMerger_AlphaMixer<4> : public ColorMerger_AlphaHandler<4>
00915 {
00916 typedef PixelSize2Type<4>::PixelType PixelType;
00917 protected:
00918 void assign ( PixelType src, PixelType* dest )
00919 {
00920
00921 if ( this->isOpaque(src ) ) {
00922 *dest = ((*dest >> 1) & 0x7f7f7f7f) + ((src >> 1) & 0x7f7f7f7f);
00923 }
00924 };
00925 public:
00926 ColorMerger_AlphaMixer ( NullParamType npt = nullParam )
00927 {}
00928 ;
00929 };
00930
00931
00932
00933 extern const int ColorMerger_Alpha_XLAT_Table_shadings[8];
00934
00935 template<int pixelsize>
00936 class ColorMerger_Alpha_XLAT_TableShifter : public ColorMerger_AlphaHandler<pixelsize>
00937 {
00938 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00939 const char* table;
00940 protected:
00941 void assign ( PixelType src, PixelType* dest )
00942 {
00943 if ( src == 0 || src >= 8 )
00944 return;
00945
00946 *dest = lighten_Color( *dest, ColorMerger_Alpha_XLAT_Table_shadings[src] );
00947
00948
00949
00950
00951
00952
00953 };
00954
00955 public:
00956 void setNeutralTranslationTable( const char* translationTable )
00957 {
00958 table = translationTable;
00959 };
00960
00961 ColorMerger_Alpha_XLAT_TableShifter( NullParamType npt = nullParam ) : table ( NULL )
00962 {}
00963 ;
00964 ColorMerger_Alpha_XLAT_TableShifter ( const char* translationTable ) : table ( translationTable )
00965 {}
00966 ;
00967 };
00968
00969 template<>
00970 class ColorMerger_Alpha_XLAT_TableShifter<1> : public ColorMerger_AlphaHandler<1>
00971 {
00972 typedef PixelSize2Type<1>::PixelType PixelType;
00973 const char* table;
00974 protected:
00975 void assign ( PixelType src, PixelType* dest )
00976 {
00977
00978 if ( this->isOpaque(src ) ) {
00979 *dest = table[ *dest + src*256 ];
00980 }
00981 };
00982
00983 public:
00984 void setNeutralTranslationTable( const char* translationTable )
00985 {
00986 table = translationTable;
00987 };
00988
00989 ColorMerger_Alpha_XLAT_TableShifter( NullParamType npt = nullParam ) : table ( NULL )
00990 {}
00991 ;
00992 ColorMerger_Alpha_XLAT_TableShifter ( const char* translationTable ) : table ( translationTable )
00993 {}
00994 ;
00995 };
00996
00997
00998 template<int pixelsize>
00999 class ColorMerger_Brightness
01000 {
01001 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01002 float b;
01003 public:
01004
01005 void assign ( PixelType src, PixelType* dest ) const
01006 {
01007 PixelType d = 0;
01008 for ( int i = 0; i < 3; ++i)
01009 d |= min( max( int( float(((*dest) >> (i*8)) & 0xff) * b ), 0 ), 255) << (i*8);
01010 d |= (*dest & 0xff000000);
01011
01012 *dest = d;
01013 };
01014
01015 ColorMerger_Brightness( float brightness )
01016 {
01017 b = brightness;
01018 };
01019 };
01020
01021
01022 template<int pixelsize>
01023 class ColorMerger_Set
01024 {
01025 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01026 SDLmm::Color col;
01027 public:
01028
01029 void assign ( PixelType src, PixelType* dest ) const
01030 {
01031 *dest = col;
01032 };
01033
01034
01035 ColorMerger_Set( SDLmm::Color color )
01036 {
01037 col = color;
01038 };
01039 };
01040
01041
01043
01044
01045
01046 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01047 class SourcePixelSelector_Rotation: public SourcePixelSelector
01048 {
01049 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01050 int degrees;
01051 int x,y;
01052 int w,h;
01053 protected:
01054
01055 void init ( const Surface& srv )
01056 {
01057 SourcePixelSelector::init(srv);
01058 w = SourcePixelSelector::getWidth();
01059 h = SourcePixelSelector::getHeight();
01060 };
01061
01062
01063 PixelType getPixel(int x, int y)
01064 {
01065 SPoint newpos = ::getPixelRotationLocation( SPoint(x,y), w, h, degrees );
01066 return SourcePixelSelector::getPixel ( newpos.x, newpos.y );
01067 };
01068
01069 PixelType nextPixel()
01070 {
01071 return getPixel(x++, y);
01072 };
01073
01074 void skipPixels( int pixNum )
01075 {
01076 x += pixNum;
01077 };
01078
01079 int getSourcePixelSkip()
01080 {
01081 return 0;
01082 };
01083
01084 void nextLine()
01085 {
01086 x = 0;
01087 y +=1;
01088 };
01089
01090 public:
01091 void setAngle( int degrees )
01092 {
01093 this->degrees = degrees;
01094 };
01095
01096 SourcePixelSelector_Rotation( NullParamType npt = nullParam ) : degrees(0),x(0),y(0),w(0),h(0)
01097 {}
01098
01099 SourcePixelSelector_Rotation( int degreesToRotate ) : degrees(degreesToRotate),x(0),y(0),w(0),h(0)
01100 {}
01101 };
01102
01103 template<int pixelsize>
01104 class SourcePixelSelector_DirectRotation: public SourcePixelSelector_Rotation<pixelsize>
01105 {
01106 public:
01107 SourcePixelSelector_DirectRotation( NullParamType npt = nullParam )
01108 {}
01109 SourcePixelSelector_DirectRotation( int degreesToRotate ) : SourcePixelSelector_Rotation<pixelsize>(degreesToRotate)
01110 {}
01111 }
01112 ;
01113
01114
01115
01116 class RotationCache
01117 {
01118 protected:
01119 static map<int,int*> cache;
01120 static int xsize;
01121 static int ysize;
01122 };
01123
01124 template<int pixelsize>
01125 class SourcePixelSelector_CacheRotation : public RotationCache
01126 {
01127 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01128 const Surface* surface;
01129 int degrees;
01130 bool useCache;
01131 const PixelType* pixelStart;
01132 const PixelType* currentPixel;
01133 int tableIndex;
01134 int pitch;
01135 int* cacheIndex;
01136 int x,y,w,h;
01137 protected:
01138
01139 void init ( const Surface& srv )
01140 {
01141 if ( !surface ) {
01142 surface = &srv;
01143 } else {
01144 assert ( surface == &srv );
01145 }
01146 tableIndex = 0;
01147 pixelStart = currentPixel = (PixelType*)surface->pixels();
01148 pitch = srv.pitch()/sizeof(PixelType) - srv.w();
01149 w = srv.w();
01150 h = srv.h();
01151 }
01152
01153 PixelType nextPixel()
01154 {
01155 if ( useCache && degrees != 0 ) {
01156 ++currentPixel;
01157
01158 assert ( cacheIndex );
01159 int index = cacheIndex[tableIndex++];
01160 if ( index >= 0 )
01161 return pixelStart[index];
01162 else
01163 return surface->GetPixelFormat().colorkey();
01164 } else {
01165 if ( degrees == 0 ) {
01166 ++tableIndex;
01167 return *(currentPixel++);
01168 } else {
01169 SPoint newpos = ::getPixelRotationLocation( SPoint(x++,y), w, h, degrees );
01170 return getSourcePixel ( newpos.x, newpos.y );
01171 }
01172 }
01173 };
01174
01175 void skipPixels( int pixNum )
01176 {
01177 currentPixel += pixNum;
01178 tableIndex += pixNum;
01179 x += pixNum;
01180 };
01181
01182 int getSourcePixelSkip()
01183 {
01184 return 0;
01185 };
01186
01187 void nextLine()
01188 {
01189 currentPixel += pitch;
01190 ++y;
01191 x = 0;
01192 };
01193
01194 int getWidth()
01195 {
01196 return surface->w();
01197 };
01198 int getHeight()
01199 {
01200 return surface->h();
01201 };
01202
01203 private:
01204 PixelType getSourcePixel(int x, int y)
01205 {
01206 if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
01207 return surface->GetPixel(SPoint(x,y));
01208 else
01209 return surface->GetPixelFormat().colorkey();
01210 };
01211
01212
01213 public:
01214 void setAngle( const Surface& srv, int degrees )
01215 {
01216 init ( srv );
01217
01218 if ( xsize == -1 ) {
01219 xsize = surface->w();
01220 ysize = surface->h();
01221 }
01222
01223 this->degrees = degrees;
01224 if ( degrees != 0 && surface->w() == xsize && surface->h() == ysize ) {
01225 useCache = true;
01226 if ( cache.find( degrees ) == cache.end() ) {
01227 int* index = new int[surface->w() * surface->h()];
01228 cache[degrees] = index;
01229 for ( int y = 0; y < surface->h(); ++y )
01230 for ( int x = 0; x < surface->w(); ++x ) {
01231 SPoint pnt = getPixelRotationLocation( SPoint(x,y), surface->w(),surface->h(), degrees );
01232 if ( pnt.x >= 0 && pnt.y >= 0 && pnt.x < surface->w() && pnt.y < surface->h() )
01233 *index++ = pnt.x + pnt.y * surface->pitch()/pixelsize;
01234 else
01235 *index++ = -1;
01236 }
01237 }
01238 cacheIndex = cache[degrees];
01239 }
01240 }
01241
01242 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)
01243 {}
01244 ;
01245
01246 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)
01247 {
01248 setAngle ( srv, degrees );
01249 };
01250
01251 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)
01252 {
01253 setAngle ( *(p.first), p.second );
01254 };
01255
01256
01257 };
01258
01259
01260 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01261 class SourcePixelSelector_Zoom: public SourcePixelSelector
01262 {
01263 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01264 float zoomFactorX;
01265 float zoomFactorY;
01266 int x,y;
01267 protected:
01268
01269 int getWidth()
01270 {
01271 return int( zoomFactorX * SourcePixelSelector::getWidth() );
01272 };
01273 int getHeight()
01274 {
01275 return int( zoomFactorY * SourcePixelSelector::getHeight() );
01276 };
01277
01278 PixelType getPixel(int x, int y)
01279 {
01280 return SourcePixelSelector::getPixel( int(float(x) / zoomFactorX), int(float(y) / zoomFactorY));
01281 };
01282
01283 PixelType nextPixel()
01284 {
01285 return getPixel(x++, y);
01286 };
01287
01288 void skipPixels( int pixNum )
01289 {
01290 x += pixNum;
01291 };
01292
01293 int getSourcePixelSkip()
01294 {
01295 return 0;
01296 };
01297
01298 void nextLine()
01299 {
01300 x= 0;
01301 ++y;
01302 };
01303
01304 public:
01305 void setZoom( float factor )
01306 {
01307 this->zoomFactorX = factor;
01308 this->zoomFactorY = factor;
01309 };
01310 void setZoom( float factorX, float factorY )
01311 {
01312 this->zoomFactorX = factorX;
01313 this->zoomFactorY = factorY;
01314 };
01315
01316 float getZoomX()
01317 {
01318 return zoomFactorX;
01319 };
01320 float getZoomY()
01321 {
01322 return zoomFactorY;
01323 };
01324
01325 void setSize( int sourceWidth, int sourceHeight, int targetWidth, int targetHeight, bool forceSquare = true )
01326 {
01327 float zw = float(targetWidth) / float(sourceWidth);
01328 float zh = float(targetHeight)/ float(sourceHeight);
01329 if ( forceSquare )
01330 setZoom( min ( zw,zh));
01331 else
01332 setZoom( zw,zh );
01333 };
01334
01335 SourcePixelSelector_Zoom( NullParamType npt = nullParam) : zoomFactorX(1),zoomFactorY(1),x(0),y(0)
01336 {}
01337 ;
01338
01339 };
01340
01341 template<int pixelsize>
01342 class SourcePixelSelector_DirectZoom: public SourcePixelSelector_Zoom<pixelsize>
01343 {
01344 public:
01345 SourcePixelSelector_DirectZoom( NullParamType npt = nullParam)
01346 {}
01347 ;
01348 };
01349
01350
01351 class ZoomCache
01352 {
01353 protected:
01354 typedef map<float,int*> ZoomMap;
01355 static ZoomMap zoomCache;
01356 };
01357
01358
01359 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01360 class SourcePixelSelector_CacheZoom : private ZoomCache, public SourcePixelSelector
01361 {
01362 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01363 const Surface* surface;
01364 float zoomFactor;
01365
01366 int currSrcX;
01367 int currSrcY;
01368 int* xp;
01369 int* yp;
01370 int offsetx;
01371 int offsety;
01372 ZoomMap::iterator cacheit;
01373 protected:
01374
01375 int getWidth()
01376 {
01377 return int( zoomFactor * SourcePixelSelector::getWidth() );
01378 };
01379 int getHeight()
01380 {
01381 return int( zoomFactor * SourcePixelSelector::getHeight() );
01382 };
01383
01384 PixelType getPixel(int x, int y)
01385 {
01386 return SourcePixelSelector::getPixel( int(float(x) / zoomFactor), int(float(y) / zoomFactor));
01387 };
01388
01389 PixelType nextPixel()
01390 {
01391 for ( int i = 0; i < *xp; ++i )
01392 SourcePixelSelector::nextPixel();
01393 ++xp;
01394
01395 return SourcePixelSelector::nextPixel();
01396 };
01397
01398 void skipPixels( int pixNum )
01399 {
01400 int count = pixNum;
01401 for ( int i = 0; i < pixNum; ++i ) {
01402 count += *xp;
01403 ++xp;
01404 }
01405 SourcePixelSelector::skipPixels( count );
01406 };
01407
01408 int getSourcePixelSkip()
01409 {
01410 int s = SourcePixelSelector::getSourcePixelSkip();
01411 if ( s ) {
01412 s = int(floor( float(s) * zoomFactor )) -2;
01413 if ( s < 1 )
01414 return 1;
01415 else
01416 return s;
01417 } else
01418 return 0;
01419 };
01420
01421
01422 void nextLine()
01423 {
01424 SourcePixelSelector::nextLine();
01425 for ( int i = 0; i < *yp; ++i )
01426 SourcePixelSelector::skipWholeLine();
01427
01428 xp = &cacheit->second[offsetx];
01429 yp++;
01430 };
01431
01432
01433 public:
01434
01435
01436 void setZoomOffset( int x, int y )
01437 {
01438 offsetx = x;
01439 offsety = y;
01440
01441
01442
01443
01444 }
01445
01446
01447 void setZoom( float factor )
01448 {
01449 this->zoomFactor = factor;
01450 assert ( factor > 0 );
01451 assert ( factor <= 1 );
01452
01453 cacheit = zoomCache.find( factor );
01454 if ( cacheit == zoomCache.end() ) {
01455 int size = max ( SDLmm::Display::GetDisplay().w(), SDLmm::Display::GetDisplay().h() );
01456
01457 int* buf = new int[size+1];
01458 buf[0] = 0;
01459
01460 for ( int i = 0; i < size; ++i ) {
01461 int a1 = int( floor( float(i) / zoomFactor ));
01462 int a2 = int( floor( float(i+1) / zoomFactor ));
01463
01464 buf[i+1] = a2 - a1 - 1;
01465 }
01466
01467 zoomCache[zoomFactor] = buf;
01468 cacheit = zoomCache.find( factor );
01469 }
01470 xp = &cacheit->second[offsetx];
01471 yp = &cacheit->second[offsety];
01472 }
01473
01474 SourcePixelSelector_CacheZoom( NullParamType npt = nullParam ) : surface(NULL), zoomFactor(1), xp(NULL), yp(NULL), offsetx(0), offsety(0)
01475 {
01476 cacheit = zoomCache.end();
01477 };
01478
01479 SourcePixelSelector_CacheZoom( float zoom ) : surface(NULL), zoomFactor(1), xp(NULL), yp(NULL), offsetx(0), offsety(0)
01480 {
01481 cacheit = zoomCache.end();
01482 setZoom ( zoom );
01483 };
01484
01485
01486 };
01487
01488
01489
01490
01491 template<int pixelsize, class SourcePixelSelector = SourcePixelSelector_Plain<pixelsize> >
01492 class SourcePixelSelector_Flip: public SourcePixelSelector
01493 {
01494 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01495 bool hflip;
01496 bool vflip;
01497 int x,y;
01498 int w,h;
01499 protected:
01500
01501 void init ( const Surface& srv )
01502 {
01503 SourcePixelSelector::init(srv);
01504 w = SourcePixelSelector::getWidth()-1;
01505 h = SourcePixelSelector::getHeight()-1;
01506 };
01507
01508
01509
01510 PixelType getPixel(int x, int y)
01511 {
01512 return SourcePixelSelector::getPixel( hflip? w-x : x , vflip ? h-y : y );
01513 };
01514
01515 PixelType nextPixel()
01516 {
01517 return getPixel(x++, y);
01518 };
01519
01520 void skipPixels( int pixNum )
01521 {
01522 x += pixNum;
01523 };
01524
01525 int getSourcePixelSkip()
01526 {
01527 return 0;
01528 };
01529
01530 void nextLine()
01531 {
01532 x= 0;
01533 ++y;
01534 };
01535
01536 public:
01537 void setFlipping( bool horizontal, bool vertical )
01538 {
01539 hflip = horizontal;
01540 vflip = vertical;
01541 };
01542
01543 SourcePixelSelector_Flip( NullParamType npt = nullParam) : hflip(false),vflip(false),x(0),y(0),w(0),h(0)
01544 {}
01545 ;
01546
01547 SourcePixelSelector_Flip( int flip) : hflip(flip&1),vflip(flip&2),x(0),y(0),w(0),h(0)
01548 {}
01549 ;
01550
01551 };
01552
01553 template<int pixelsize>
01554 class SourcePixelSelector_DirectFlip : public SourcePixelSelector_Flip<pixelsize>
01555 {
01556 public:
01557 SourcePixelSelector_DirectFlip( NullParamType npt = nullParam)
01558 {}
01559 ;
01560 SourcePixelSelector_DirectFlip( int flip) : SourcePixelSelector_Flip<pixelsize>(flip)
01561 {}
01562 ;
01563 };
01564
01565
01566 template<int pixelsize>
01567 class SourcePixelSelector_Rectangle: public SourcePixelSelector_Plain<pixelsize>
01568 {
01569 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01570 int x,y,x1,y1;
01571 int w,h;
01572 protected:
01573 SourcePixelSelector_Rectangle() : x(0),y(0),x1(0),y1(0),w(0),h(0)
01574 {}
01575 ;
01576 public:
01577
01578 SourcePixelSelector_Rectangle( const SDLmm::SRect& rect ) : x(0),y(0),x1(0),y1(0),w(0),h(0)
01579 {
01580 setSrcRectangle( rect );
01581 }
01582 protected:
01583
01584 int getWidth()
01585 {
01586 return min(w, SourcePixelSelector_Plain<pixelsize>::getWidth() -x1 );
01587 };
01588 int getHeight()
01589 {
01590 return min(h, SourcePixelSelector_Plain<pixelsize>::getHeight()-y1 );
01591 };
01592
01593
01594 PixelType getPixel(int x, int y)
01595 {
01596 return SourcePixelSelector_Plain<pixelsize>::getPixel( x + x1, y + y1 );
01597 };
01598
01599 PixelType nextPixel()
01600 {
01601 return getPixel(x++, y);
01602 };
01603
01604 void skipWholeLine()
01605 {
01606 ++y;
01607 };
01608
01609 void skipPixels( int pixNum )
01610 {
01611 x += pixNum;
01612 };
01613
01614 int getSourcePixelSkip()
01615 {
01616 return 0;
01617 };
01618
01619 void nextLine()
01620 {
01621 x= 0;
01622 ++y;
01623 };
01624
01625 public:
01626 void setSrcRectangle( SPoint pos, int width, int height )
01627 {
01628 x1 = pos.x;
01629 y1 = pos.y;
01630 w = width;
01631 h = height;
01632 };
01633 void setSrcRectangle( const SDLmm::SRect& rect )
01634 {
01635 x1 = rect.x;
01636 y1 = rect.y;
01637 w = rect.w;
01638 h = rect.h;
01639 };
01640
01641 };
01642
01643 template<int pixelsize>
01644 class SourcePixelSelector_DirectRectangle
01645 {
01646 typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
01647 int y,x1,y1;
01648 int w,h;
01649
01650 const PixelType* pointer;
01651 const PixelType* startPointer;
01652 int pitch;
01653 int linelength;
01654 const Surface* surface;
01655 protected:
01656 SourcePixelSelector_DirectRectangle() : y(0),x1(0),y1(0),w(0),h(0),pointer(NULL), surface(NULL)
01657 {}
01658 ;
01659
01660 int getWidth()
01661 {
01662 return min(w, surface->w() -x1 );
01663 };
01664 int getHeight()
01665 {
01666 return min(h, surface->h()-y1 );
01667 };
01668
01669
01670 void init ( const Surface& srv )
01671 {
01672 surface = &srv;
01673 startPointer = pointer = (const PixelType*)(srv.pixels());
01674 linelength = srv.pitch()/sizeof(PixelType);
01675 pitch = linelength - w -1 ;
01676 y = y1;
01677 pointer += x1 + y1 * linelength;
01678 };
01679
01680 PixelType getPixel(int x, int y)
01681 {
01682 x += x1;
01683 y += y1;
01684 if ( x >= 0 && y >= 0 && x < surface->w() && y < surface->h() )
01685 return surface->GetPixel(SPoint(x,y));
01686 else
01687 return surface->GetPixelFormat().colorkey();
01688 };
01689
01690
01691 PixelType nextPixel()
01692 {
01693 return *(pointer++);
01694 };
01695
01696
01697 void skipWholeLine()
01698 {
01699 pointer += linelength;
01700 ++y;
01701 };
01702
01703 void skipPixels( int pixNum )
01704 {
01705 pointer += pixNum;
01706 };
01707
01708 int getSourcePixelSkip()
01709 {
01710 return 0;
01711 };
01712
01713 void nextLine()
01714 {
01715 pointer = startPointer + x1 + (y++) * linelength;
01716 };
01717
01718 public:
01719 void setSrcRectangle( SPoint pos, int width, int height )
01720 {
01721 x1 = pos.x;
01722 y1 = pos.y;
01723 w = width;
01724 h = height;
01725 };
01726 void setSrcRectangle( const SDLmm::SRect& rect )
01727 {
01728 x1 = rect.x;
01729 y1 = rect.y;
01730 w = rect.w;
01731 h = rect.h;
01732 };
01733
01734 };
01735
01736
01737 class TargetPixelSelector_Rect {
01738 SDLmm::SRect rect;
01739 int x2,y2;
01740 int xrange;
01741 int w,h;
01742 SPoint pos;
01743 protected:
01744 int skipTarget( int x, int y )
01745 {
01746 int nx = x + pos.x;
01747 int ny = y + pos.y;
01748 if ( nx >= rect.x && ny >= rect.y && nx < x2 && ny < y2 )
01749 return 0;
01750 else {
01751 if ( ny < rect.y )
01752 return xrange - x;
01753 else
01754 if ( nx < rect.x )
01755 return rect.x - nx;
01756 else
01757 if (ny >= y2 )
01758 return -1;
01759 else
01760 if ( nx >= x2 )
01761 return xrange - x;
01762 else
01763 return 1;
01764 }
01765 };
01766 void init( const Surface& srv, const SPoint& position, int xrange, int yrange )
01767 {
01768 w = srv.w();
01769 h = srv.h();
01770 pos = position;
01771 this->xrange = xrange;
01772 };
01773
01774 public:
01775 void setTargetRect( const SDL_Rect& r )
01776 {
01777 rect = r;
01778 x2 = r.x + r.w;
01779 y2 = r.y + r.h;
01780 };
01781
01782 void setClippingRect( SDL_Surface* srv )
01783 {
01784 setTargetRect( srv->clip_rect );
01785 };
01786
01787 TargetPixelSelector_Rect ( NullParamType npt = nullParam ) :w(0xffffff),h(0xffffff) {};
01788 };
01789
01790
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805 #endif
01806