fs/ras/fsDraw.h

Go to the documentation of this file.
00001 /*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
00002 /*                          _______      ______    ______          __      */
00003 /*  ~ ~ ~ ~ ~ ~ ~ ~ ~ ~    / ____(_)___ / ___ /)  / ____/___  ____/ /__    */
00004 /*      [fsDraw]          / /_  / / __ \\__ \|/  / /   / __ \/ __  / _ \   */
00005 /*       rev.  3         / __/ / / /_/ /__/ /   / /___/ /_/ / /_/ /  __/   */
00006 /*    26th May 2006     /_/   /_/ ,___/____/    \____/\____/\__,_/\___/    */
00007 /*     [ ] stable              /_/ (c) 2006 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_FSDRAW_H
00015 #define FS_RAS_FSDRAW_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 nsDraw {
00058 //---------------------------------------------------------------------------
00060 struct PxFmt8888_t { unsigned char r, g, b, a; };
00061 //---------------------------------------------------------------------------
00063 struct Cl8888DwPcy_t
00064 {
00065     typedef PxFmt8888_t PxFmt_t;
00066 };
00067 //---------------------------------------------------------------------------
00068 } // namespace nsDraw
00069 //---------------------------------------------------------------------------
00071 
00073 template <typename TDwPcy>
00074 void DrawLine(int nX1, int nY1, int nX2, int nY2, const nsDraw::PxFmt8888_t
00075  &Clr, typename TDwPcy::PxFmt_t *pDst, int nDstW, int nDstH)
00076 {
00077     FS_ASSERT(pDst);
00078     FS_ASSERT(nDstW > 0 && nDstH > 0);
00079     
00080     if(
00081      nX1 < 0 || nY1 < 0 || nY2 < 0 || nX2 < 0 ||
00082      nX1 >= nDstW || nY1 >= nDstH ||
00083      nX2 >= nDstW || nY2 >= nDstH
00084     ) return; // no clipping at the moment
00085 
00086     struct Abs { static int Do(int v) { return v >= 0 ? v : -v; }};
00087     
00088     int nDX = Abs::Do(nX2 - nX1);
00089     int nDY = Abs::Do(nY2 - nY1);
00090 
00091     bool bSteep = nDY > nDX;
00092     if(bSteep)
00093     {
00094         struct Swap { static void Do(int &v1, int &v2)
00095         { int t = v1; v1 = v2; v2 = t; }};
00096     
00097         Swap::Do(nDX, nDY);
00098         Swap::Do(nX1, nY1);
00099         Swap::Do(nX2, nY2);
00100     }
00101 
00102     int nError = 0;
00103     int nDE = nDY;
00104     int &x = bSteep ? nY1 : nX1;
00105     int &y = bSteep ? nX1 : nY1;
00106     int nStepX = (nX1 < nX2) ? 1 : -1;
00107     int nStepY = (nY1 < nY2) ? 1 : -1;
00108         
00109     typedef typename TDwPcy::PxFmt_t Px_t;
00110     Px_t Px(Clr);
00111 
00112     FS_ASSERT(x >= 0 && y >= 0 && x < nDstW && y < nDstH);
00113     pDst[y * nDstW + x] = Px;
00114     
00115     while(nX1 != nX2)
00116     {
00117         nX1 += nStepX;
00118         nError += nDE;
00119         if((nError << 1) >= nDX)
00120         {
00121             nY1 += nStepY;
00122             nError -= nDX;
00123         }
00124         
00125         FS_ASSERT(x >= 0 && y >= 0 && x < nDstW && y < nDstH);
00126         pDst[y * nDstW + x] = Px;
00127     }
00128 }
00129 //---------------------------------------------------------------------------
00131 
00133 template <typename TDwPcy>
00134 void DrawCirc(int nX, int nY, int nR, const nsDraw::PxFmt8888_t &Clr,
00135  typename TDwPcy::PxFmt_t *pDst, int nDstW, int nDstH)
00136 {
00137     FS_ASSERT(pDst);
00138     FS_ASSERT(nDstW > 0 && nDstH > 0);
00139 
00140     if(
00141      nX < nR || nY < nR ||
00142      nX >= nDstW - nR || nY >= nDstH - nR
00143     ) return; // no clipping at the moment
00144 
00145     int x = 0;
00146     int y = nR;
00147     int nD = 3 - (2 * nR);
00148     
00149     typedef typename TDwPcy::PxFmt_t Px_t;
00150     Px_t Px(Clr);
00151     
00152     struct Offset
00153     {
00154         int m_w, m_h;
00155         Offset(int w, int h) : m_w(w), m_h(h) {}
00156         int Do(int x, int y) const
00157         {
00158             FS_ASSERT(x >= 0 && y >= 0 && x < m_w && y < m_h);
00159             return y * m_w + x;
00160         }
00161     };
00162     
00163     const Offset Off(nDstW, nDstH);
00164     while(x <= y)
00165     {
00166         pDst[Off.Do(nX + y, nY + x)] = Px;
00167         pDst[Off.Do(nX - y, nY + x)] = Px;
00168         pDst[Off.Do(nX + y, nY - x)] = Px;
00169         pDst[Off.Do(nX - y, nY - x)] = Px;
00170         pDst[Off.Do(nX + x, nY + y)] = Px;
00171         pDst[Off.Do(nX - x, nY + y)] = Px;
00172         pDst[Off.Do(nX + x, nY - y)] = Px;
00173         pDst[Off.Do(nX - x, nY - y)] = Px;
00174         
00175         if(nD < 0) nD += (4 * x) + 6;
00176         else { nD += (4 * (x - y)) + 10; --y; }
00177         ++x;
00178     }
00179 }
00180 //---------------------------------------------------------------------------
00181 }} // namespace fs::ras
00182 //---------------------------------------------------------------------------
00183 #endif // FS_RAS_FSDRAW_H

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