00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
00219 if (deltax >= deltay)
00220 {
00221
00222
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
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
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
00259 x = x1;
00260 y = y1;
00261
00262
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
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