Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

drawing.h

Go to the documentation of this file.
00001 /*
00002     This file is part of Advanced Strategic Command; http://www.asc-hq.de
00003     Copyright (C) 1994-2004  Martin Bickel  and  Marc Schellenberger
00004  
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009  
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013     GNU General Public License for more details.
00014  
00015     You should have received a copy of the GNU General Public License
00016     along with this program; see the file COPYING. If not, write to the
00017     Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00018     Boston, MA  02111-1307  USA
00019 */
00020 
00021 #ifndef drawingH
00022  #define drawingH
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  #include "blitter.h"
00030 
00031 #include "../misc.h"
00032  #include "../palette.h"
00033  // #include "../basegfx.h"
00034 
00035 
00036 
00037 template<int BytePerPixel, class ColorMergerUL, class ColorMergerLR>
00038 void rectangle( Surface& surface, const SPoint& pos, int w, int h, const ColorMergerUL& ul, const ColorMergerLR& lr )
00039 {
00040    SurfaceLock lock( surface );
00041    typedef typename PixelSize2Type<BytePerPixel>::PixelType TargetPixelType;
00042 
00043    TargetPixelType* pix = (TargetPixelType*)( surface.pixels() );
00044    pix += pos.y * surface.pitch()/BytePerPixel + pos.x;
00045 
00046    int pitch = surface.pitch()/BytePerPixel;
00047 
00048    h -= 1;
00049    w -= 1;
00050 
00051    for ( int x = 0; x <= w; ++x )
00052       ul.assign ( 1, (pix+x) );
00053 
00054    for ( int y = 0; y <= h; ++y )
00055       ul.assign ( 1, (pix+y*pitch) );
00056 
00057    for ( int x = 0; x <= w; ++x )
00058       lr.assign ( 1, (pix+x+h*pitch) );
00059 
00060    for ( int y = 0; y <= h; ++y )
00061       lr.assign ( 1, (pix+y*pitch+w) );
00062 
00063 }
00064 
00065 template<int BytePerPixel, class ColorMergerUL, class ColorMergerLR >
00066 void rectangle( Surface& surface, const SPoint& pos, int w, int h, const ColorMergerUL& ul, const ColorMergerLR& lr, const SDLmm::SRect& clip )
00067 {
00068    SurfaceLock lock( surface );
00069    typedef typename PixelSize2Type<BytePerPixel>::PixelType TargetPixelType;
00070 
00071    TargetPixelType* pix = (TargetPixelType*)( surface.pixels() );
00072    pix += pos.y * surface.pitch()/BytePerPixel + pos.x;
00073 
00074    int pitch = surface.pitch()/BytePerPixel;
00075 
00076    h -= 1;
00077    w -= 1;
00078 
00079    for ( int x = 0; x <= w; ++x )
00080       if ( clip.Contains( SPoint( pos.x+x, pos.y )))
00081          ul.assign ( 1, (pix+x) );
00082 
00083    for ( int y = 0; y <= h; ++y )
00084       if ( clip.Contains( SPoint( pos.x, pos.y + y)))
00085          ul.assign ( 1, (pix+y*pitch) );
00086 
00087    for ( int x = 0; x <= w; ++x )
00088       if ( clip.Contains( SPoint( pos.x+x, pos.y + h )))
00089          lr.assign ( 1, (pix+x+h*pitch) );
00090 
00091    for ( int y = 0; y <= h; ++y )
00092       if ( clip.Contains( SPoint( pos.x+w, pos.y +y )))
00093          lr.assign ( 1, (pix+y*pitch+w) );
00094 
00095 }
00096 
00097 
00098 
00099 
00100 
00101 template<int BytePerPixel, class ColorMerger>
00102 void paintFilledRectangle( Surface& surface, const SPoint& pos, int w, int h, const ColorMerger& ul )
00103 {
00104    if ( w <= 0 || h <= 0 )
00105       return;
00106 
00107    SurfaceLock lock( surface );
00108 
00109    typedef typename PixelSize2Type<BytePerPixel>::PixelType TargetPixelType;
00110    ul.init( surface );
00111 
00112    TargetPixelType* pix = (TargetPixelType*)( surface.pixels() );
00113    pix += pos.y * surface.pitch()/BytePerPixel + pos.x;
00114 
00115    int pitch = surface.pitch()/BytePerPixel - w;
00116 
00117    h -= 1;
00118    w -= 1;
00119 
00120    for ( int y = 0; y <= h; ++y ) {
00121       for ( int x = 0; x <= w; ++x ) {
00122          ul.assign ( pix );
00123          ++pix;
00124       }
00125       pix += pitch;
00126    }
00127 }
00128 
00129 extern char saturationTranslationTable[256][256];
00130 
00131 
00132 inline SDLmm::Color lighten_Color( SDLmm::Color color, int factor16 )
00133 {
00134    return saturationTranslationTable[color & 0xff][factor16] |
00135           (saturationTranslationTable[(color >> 8) & 0xff][factor16] << 8 ) |
00136           (saturationTranslationTable[(color >> 16) & 0xff][factor16] << 16 ) |
00137           (color & 0xff000000);
00138 }
00139 
00140 inline void lighten_Color( SDLmm::Color* color, int factor16 )
00141 {
00142    *color = lighten_Color( *color, factor16 );
00143 };
00144 
00145 inline SDL_Color lighten_Color( const SDL_Color& color, int factor16 )
00146 {
00147    SDL_Color c  = color;
00148    c.r =  saturationTranslationTable[color.r & 0xff][factor16];
00149    c.g =  saturationTranslationTable[color.g & 0xff][factor16];
00150    c.b =  saturationTranslationTable[color.b & 0xff][factor16];
00151    return c;
00152 }
00153 
00154 
00155 template< int pixelsize,
00156 template<int> class ColorMerger >
00157 class PutPixel: public ColorMerger<pixelsize>
00158 {
00159       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00160       Surface& surf;
00161    public:
00162       PutPixel( Surface& surface ) : surf ( surface )
00163       {
00164          ColorMerger<pixelsize>::init( surface );
00165       };
00166 
00167       void set( SPoint pos, PixelType src )
00168       {
00169          PixelType* pix = (PixelType*)( surf.pixels() );
00170          pix += pos.y * surf.pitch()/pixelsize + pos.x;
00171 
00172          assign ( src, pix );
00173       };
00174 };
00175 
00176 template< int pixelsize, class ColorMerger >
00177 class PutPixel2
00178 {
00179       typedef typename PixelSize2Type<pixelsize>::PixelType PixelType;
00180       Surface& surf;
00181       const ColorMerger& colormerger;
00182    public:
00183       PutPixel2( Surface& surface, const ColorMerger& cm ) : surf ( surface ), colormerger(cm)
00184       {
00185       };
00186 
00187       void set( SPoint pos, PixelType src )
00188       {
00189          PixelType* pix = (PixelType*)( surf.pixels() );
00190          pix += pos.y * surf.pitch()/pixelsize + pos.x;
00191 
00192          colormerger.assign ( src, pix );
00193       };
00194 };
00195 
00196 
00197 template< int pixelsize, class ColorMerger >
00198 void drawLine ( Surface& surface, const ColorMerger& cm, const SPoint& pos, const SPoint& pos2  )
00199 {
00200    PutPixel2<pixelsize, ColorMerger> pp ( surface, cm );
00201    int      i, deltax, deltay, numpixels, d, dinc1, dinc2, x, xinc1, xinc2, y, yinc1, yinc2;
00202 
00203    int x1 = pos.x;
00204    int y1 = pos.y;
00205    int x2 = pos2.x;
00206    int y2 = pos2.y;
00207 
00208    /*  calculate deltax and deltay for initialisation  */
00209     
00210    deltax = x2 - x1;
00211    if ( deltax < 0 )
00212       deltax = -deltax;
00213 
00214    deltay = y2 - y1;
00215    if ( deltay < 0 )
00216       deltay = -deltay;
00217 
00218    /*  initialize all vars based on which is the independent variable  */
00219    if (deltax >= deltay)
00220    {
00221 
00222       /*  x is independent variable  */
00223       numpixels = deltax + 1;
00224       d = (2 * deltay) - deltax;
00225       dinc1 = deltay << 1;
00226       dinc2 = (deltay - deltax) << 1;
00227       xinc1 = 1;
00228       xinc2 = 1;
00229       yinc1 = 0;
00230       yinc2 = 1;
00231    }
00232    else
00233    {
00234 
00235       /*  y is independent variable  */
00236       numpixels = deltay + 1;
00237       d = (2 * deltax) - deltay;
00238       dinc1 = deltax << 1;
00239       dinc2 = (deltax - deltay) << 1;
00240       xinc1 = 0;
00241       xinc2 = 1;
00242       yinc1 = 1;
00243       yinc2 = 1;
00244    }
00245 
00246    /*  make sure x and y move in the right directions  */
00247    if (x1 > x2)
00248    {
00249       xinc1 = -xinc1;
00250       xinc2 = -xinc2;
00251    }
00252    if (y1 > y2)
00253    {
00254       yinc1 = -yinc1;
00255       yinc2 = -yinc2;
00256    }
00257 
00258    /*  start drawing at <x1, y1>  */
00259    x = x1;
00260    y = y1;
00261 
00262    /*  draw the pixels  */
00263    for (i = 1; i <= numpixels; i++)
00264    {
00265       pp.set( SPoint(x, y), 1 );
00266 
00267 
00268       if (d < 0)
00269       {
00270          d = d + dinc1;
00271          x = x + xinc1;
00272          y = y + yinc1;
00273       }
00274       else
00275       {
00276          d = d + dinc2;
00277          x = x + xinc2;
00278          y = y + yinc2;
00279       }
00280    }
00281 }
00282 
00283 
00284 
00285 template<int pixelsize>
00286       class ColorMerger_AlphaLighter
00287 {}
00288 ;
00289 
00290 template<>
00291       class ColorMerger_AlphaLighter<1> : public ColorMerger_AlphaHandler<1>
00292 {
00293    typedef PixelSize2Type<1>::PixelType PixelType;
00294    protected:
00295 
00296       void assign ( PixelType src, PixelType* dest )
00297       {
00298          // not defined
00299       };
00300    public:
00301       ColorMerger_AlphaLighter ( NullParamType npt = nullParam) {} ;
00302       ColorMerger_AlphaLighter ( float factor ) {} ;
00303 };
00304 
00305 
00306 template<>
00307       class ColorMerger_AlphaLighter<4> : public ColorMerger_AlphaHandler<4>
00308 {
00309    typedef PixelSize2Type<4>::PixelType PixelType;
00310    int factor16;
00311    protected:
00312 
00313       void init( const Surface& srf )
00314       {
00315          ColorMerger_AlphaHandler<4>::init(srf);
00316       };
00317 
00318 
00319       void assign ( PixelType src, PixelType* dest )
00320       {
00321          if ( isOpaque(src ) ) 
00322             *dest = lighten_Color( *dest, factor16 );
00323          
00324       };
00325    public:
00326       ColorMerger_AlphaLighter ( NullParamType npt = nullParam) : factor16( 16 )
00327       {}
00328       ;
00329       ColorMerger_AlphaLighter ( float factor ) : factor16 ( int ( factor * 16 ))
00330       {}
00331       ;
00332 };
00333 
00334 
00335 #endif
00336 

Generated on Tue Jun 24 01:27:39 2008 for Advanced Strategic Command by  doxygen 1.4.2