fs/ras/fsBitBlt.h

Go to the documentation of this file.
00001 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00002 /*                          _______      ______    ______          __      */
00003 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~    / ____(_)___ / ___ /)  / ____/___  ____/ /__    */
00004 /*     [fsBitBlt]         / /_  / / __ \\__ \|/  / /   / __ \/ __  / _ \   */
00005 /*       rev. 6          / __/ / / /_/ /__/ /   / /___/ /_/ / /_/ /  __/   */
00006 /*    6th Feb 2007      /_/   /_/ ,___/____/    \____/\____/\__,_/\___/    */
00007 /*     [x] stable              /_/ (c) 2006-7 Filip STOKLAS (FipS)         */
00008 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~       http://HOLE.4FipS.com/fips_code.php          */
00009 /*                                                                         */
00010 /* This code is free for personal and commercial use. You may redistribute */
00011 /* it by any means. If you use the code for your own projects please give  */
00012 /* me credit. Please send a bug report. Don't alter or remove this header! */
00013 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00014 #ifndef FS_RAS_FSBITBLT_H
00015 #define FS_RAS_FSBITBLT_H
00016 //---------------------------------------------------------------------------
00017 #if defined(FS_INCLUDE_USERDEFS) // inject user definition file on request
00018 #   include <fs/fsUserDefs.h>
00019 #endif
00020 //---------------------------------------------------------------------------
00021 // >>> COMMON SUPPORT BLOCK (rev. 6)
00022 #if defined(FS_HAS_FSASSERT)
00023 #   include <fs/sys/fsAssert.h>
00024 #else
00025 #   include <cassert>
00026 #   if !defined(FS_ASSERT)
00027 #       define FS_ASSERT(exp) assert(exp)
00028 #   endif
00029 #   if !defined(FS_ASSERT_MSG)
00030 #       define FS_ASSERT_MSG(exp, msg) assert(exp && msg)
00031 #   endif
00032 #   if !defined(FS_VERIFY)
00033 #       define FS_VERIFY(exp) \
00034         { bool bExp = !!(exp); assert(bExp && #exp); bExp; }
00035 #   endif
00036 #   if !defined(FS_VERIFY_MSG)
00037 #       define FS_VERIFY_MSG(exp, msg) \
00038         { bool bExp = !!(exp); assert(bExp && #exp && msg); bExp; }
00039 #   endif
00040 #   if !defined(FS_STATIC_ASSERT)
00041 #       define FS_STATIC_ASSERT(exp) { char error[(exp) ? 1 : 0]; error; }
00042 #   endif
00043 #endif
00044 #if !defined(FS_VERIFY_RETURN)
00045 #   define FS_VERIFY_RETURN(exp) \
00046     if(!(exp)) { FS_ASSERT_MSG(0, #exp "<return>"); return; }
00047 #endif
00048 #if !defined(FS_VERIFY_RETURN_VAL)
00049 #   define FS_VERIFY_RETURN_VAL(exp, ret) \
00050     if(!(exp)) { FS_ASSERT_MSG(0, #exp "<returns:>" #ret); return (ret); }
00051 #endif
00052 // <<< COMMON SUPPORT BLOCK (rev. 6)
00053 //---------------------------------------------------------------------------
00054 namespace fs { namespace ras {
00055 //---------------------------------------------------------------------------
00057 namespace nsBitBlt {
00058 //---------------------------------------------------------------------------
00060 struct PxFmt888_t { unsigned char r, g, b; };
00062 struct PxFmt8888_t { unsigned char r, g, b, a; };
00063 //---------------------------------------------------------------------------
00065 struct Cl888CpPcy_t
00066 {
00067     typedef PxFmt888_t SrcPxFmt_t;
00068     typedef PxFmt888_t DstPxFmt_t;
00069     static void Copy(const SrcPxFmt_t &Src, DstPxFmt_t &Dst)
00070     {
00071         FS_STATIC_ASSERT(sizeof(SrcPxFmt_t) == 3);
00072         FS_STATIC_ASSERT(sizeof(DstPxFmt_t) == 3);
00073         Dst = Src;
00074     }
00075 };
00076 //---------------------------------------------------------------------------
00078 struct Cl8888CpPcy_t
00079 {
00080     typedef PxFmt8888_t SrcPxFmt_t;
00081     typedef PxFmt8888_t DstPxFmt_t;
00082     static void Copy(const SrcPxFmt_t &Src, DstPxFmt_t &Dst)
00083     {
00084         FS_STATIC_ASSERT(sizeof(SrcPxFmt_t) == 4);
00085         FS_STATIC_ASSERT(sizeof(DstPxFmt_t) == 4);
00086         Dst = Src;
00087     }
00088 };
00089 //---------------------------------------------------------------------------
00091 struct Cl8888TrCpPcy_t
00092 {
00093     typedef PxFmt8888_t SrcPxFmt_t;
00094     typedef PxFmt8888_t DstPxFmt_t;
00095     static void Copy(const SrcPxFmt_t &Src, DstPxFmt_t &Dst)
00096     {
00097         FS_STATIC_ASSERT(sizeof(SrcPxFmt_t) == 4);
00098         FS_STATIC_ASSERT(sizeof(DstPxFmt_t) == 4);
00099         Dst = Src.a ? Src : Dst;
00100     }
00101 };
00102 //---------------------------------------------------------------------------
00104 struct Cl888to8888CpPcy_t
00105 {
00106     typedef PxFmt888_t SrcPxFmt_t;
00107     typedef PxFmt8888_t DstPxFmt_t;
00108 
00109     static void Copy(const SrcPxFmt_t &Src, DstPxFmt_t &Dst)
00110     {
00111         FS_STATIC_ASSERT(sizeof(SrcPxFmt_t) == 3);
00112         FS_STATIC_ASSERT(sizeof(DstPxFmt_t) == 4);
00113         Dst.r = Src.r;
00114         Dst.g = Src.g;
00115         Dst.b = Src.b;
00116     }
00117 };
00118 //---------------------------------------------------------------------------
00119 } // namespace nsBitBlt
00120 //---------------------------------------------------------------------------
00122 
00126 template <typename TCpPcy>
00127 void BitBlt(
00128  typename const TCpPcy::SrcPxFmt_t *pSrc,
00129  int nSrcW,
00130  int /*nSrcH*/,
00131  int nSrcPosX,
00132  int nSrcPosY,
00133  int nRegW,
00134  int nRegH,
00135  typename TCpPcy::DstPxFmt_t *pDst,
00136  int nDstW,
00137  int nDstH,
00138  int nDstPosX,
00139  int nDstPosY,
00140  int nDstClipX1 = 0,
00141  int nDstClipY1 = 0,
00142  int nDstClipX2 = -1, // -1 stands for nDstW
00143  int nDstClipY2 = -1  // -1 stands for nDstH
00144 )
00145 //---------------------------------------------------------------------------
00146 {
00147     FS_ASSERT(pSrc && pDst);
00148     
00149     //--- PREPARE BUFFERS ---
00150     
00151     typedef typename TCpPcy::SrcPxFmt_t SrcPxFmt_t;
00152     typedef typename TCpPcy::DstPxFmt_t DstPxFmt_t;
00153     
00154     const SrcPxFmt_t *pSrcCur = pSrc + nSrcPosY * nSrcW + nSrcPosX;
00155     DstPxFmt_t *pDstCur = pDst + nDstPosY * nDstW + nDstPosX;
00156 
00157     //--- APPLY CLIPPING ---
00158 
00159     nDstClipX2 = nDstClipX2 != -1 ? nDstClipX2 : nDstW;
00160     nDstClipY2 = nDstClipY2 != -1 ? nDstClipY2 : nDstH;
00161 
00162     // right
00163     if(nDstPosX + nRegW > nDstClipX2)
00164     {
00165         nRegW = nDstClipX2 - nDstPosX;
00166     }
00167 
00168     // bottom
00169     if(nDstPosY + nRegH > nDstClipY2)
00170     {
00171         nRegH = nDstClipY2 - nDstPosY;
00172     }    
00173 
00174     // left
00175     if(nDstPosX < nDstClipX1)
00176     {
00177         const int nLeftClip = nDstClipX1 - nDstPosX;
00178         nRegW -= nLeftClip;
00179         pSrcCur += nLeftClip;
00180         pDstCur += nLeftClip;
00181     }
00182 
00183     // top
00184     if(nDstPosY < nDstClipY1)
00185     {
00186         const int nTopClip = nDstClipY1 - nDstPosY;
00187         nRegH -= nTopClip;
00188         pSrcCur += nTopClip * nSrcW;
00189         pDstCur += nTopClip * nDstW;
00190     }
00191 
00192     if(nRegW <= 0 || nRegH <= 0)
00193         return; // out of the clipping region
00194 
00195     //--- TRANSFER DATA ---
00196 
00197     const int nSrcSkip = nSrcW - nRegW;
00198     const int nDstSkip = nDstW - nRegW;
00199 
00200     for(int y = nRegH; y != 0; --y)
00201     {
00202         for(int x = nRegW; x != 0; --x)
00203         {
00204             TCpPcy::Copy(*pSrcCur, *pDstCur);
00205             ++pSrcCur;
00206             ++pDstCur;
00207         }
00208 
00209         pSrcCur += nSrcSkip;
00210         pDstCur += nDstSkip;
00211     }
00212 }
00213 //---------------------------------------------------------------------------
00214 }} // namespace fs::ras
00215 //---------------------------------------------------------------------------
00216 #endif // FS_RAS_FSBITBLT_H

FipS' Code (Thu Feb 15 22:43:35 2007) - (c) Filip STOKLAS (FipS) - [ www ] [ Guest Book ]