00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00029
00030
00031
00032 #include "PocketKnife.h"
00033 #include "Image.h"
00034 #include "ImageTool.h"
00035
00036 #include <cstdio>
00037 #include <cstdlib>
00038 #include <string>
00039 #include <cstring>
00040
00041 #if defined(TARGET_HOST_WIN32) || defined(TARGET_HOST_WINCE)
00042 #include <windows.h>
00043 #endif
00044
00045
00046 namespace PN {
00047
00048
00049 void
00050 Image::clear(unsigned short nColor)
00051 {
00052 int size = width*height;
00053
00054 if((size&7)==0)
00055 {
00056 size >>= 3;
00057 unsigned int col32 = nColor | (nColor<<16);
00058 unsigned int* dst = (unsigned int*)getPixels();
00059
00060 while(size--)
00061 {
00062 dst[0] = col32;
00063 dst[1] = col32;
00064 dst[2] = col32;
00065 dst[3] = col32;
00066
00067 dst += 4;
00068 }
00069 }
00070 else
00071 {
00072 unsigned short *dst = getPixels();
00073
00074 while(size--)
00075 *dst++ = nColor;
00076 }
00077 }
00078
00079
00080 void
00081 Image::clear(int nRed, int nGreen, int nBlue)
00082 {
00083 clear(ImageTool::convertPixel24To16(nRed, nGreen, nBlue));
00084 }
00085
00086
00087 void
00088 Image::drawImage(int nX, int nY, const Image* nImage,
00089 int nSx0, int nSy0, int nSx1, int nSy1,
00090 bool nTransparent)
00091 {
00092 int sw = nImage->getWidth(),
00093 sx0 = nSx0, sy0 = nSy0, sx1 = nSx1, sy1 = nSy1,
00094 dx0 = nX, dy0 = nY, dx1 = nX+nSx1-nSx0, dy1 = nY+nSy1-nSy0;
00095
00096 if(dx0>=width || dx1<0 || dy0>=height || dy1<0)
00097 return;
00098
00099 const unsigned short* src = nImage->getPixels();
00100 unsigned short* dst = getPixels();
00101
00102 if(dx0<0)
00103 { sx0 += -dx0; dx0 = 0; }
00104 if(dy0<0)
00105 { sy0 += -dy0; dy0 = 0; }
00106
00107 if(dx1>width)
00108 { sx1 -= dx1-width; dx1 = width; }
00109 if(dy1>height)
00110 { sy1 -= dy1-height; dy1 = height; }
00111
00112 int w = sx1-sx0, h = sy1-sy0, x,y;
00113
00114 src += sy0*sw + sx0;
00115 dst += dy0*width + dx0;
00116
00117 if(!nTransparent)
00118 for(y=0; y<h; y++)
00119 {
00120 memcpy(dst, src, 2*w);
00121 dst += width;
00122 src += sw;
00123 }
00124 else
00125 {
00126 unsigned short key = nImage->getColorKey();
00127
00128 for(y=0; y<h; y++)
00129 {
00130 for(x=0; x<w; x++)
00131 {
00132 if(*src != key)
00133 *dst = *src;
00134 dst++;
00135 src++;
00136 }
00137 dst += width-w;
00138 src += sw-w;
00139 }
00140 }
00141 }
00142
00143 void
00144 Image::drawImage(int nX, int nY, const Image* nImage, bool nTransparent)
00145 {
00146 drawImage(nX, nY, nImage,
00147 0,0, nImage->getWidth(),nImage->getHeight(),
00148 nTransparent);
00149 }
00150
00151
00152 void
00153 Image::fillRect(int nX0, int nY0, int nX1, int nY1, int nRed, int nGreen, int nBlue, int nOpacity)
00154 {
00155 fillRect(nX0,nY0, nX1,nY1, ImageTool::convertPixel24To16(nRed,nGreen,nBlue), nOpacity);
00156 }
00157
00158 void
00159 Image::fillRect(int nX0, int nY0, int nX1, int nY1, unsigned short nColor, int nOpacity)
00160 {
00161 if(nX0<0) nX0 = 0;
00162 if(nY0<0) nY0 = 0;
00163 if(nX1>width) nX1 = width;
00164 if(nY1>height) nY1 = height;
00165
00166 int w,w0 = nX1-nX0, h = nY1-nY0;
00167 unsigned short* dst = (unsigned short*)getPixels();
00168
00169 dst += nX0 + nY0*width;
00170
00171 if(nOpacity==0)
00172 while(h--)
00173 {
00174 w = w0;
00175 while(w--)
00176 *dst++ = nColor;
00177
00178 dst += width-w0;
00179 }
00180 else
00181 {
00182 while(h--)
00183 {
00184 w = w0;
00185 while(w--)
00186 {
00187 *dst = ImageTool::blendPixel16(*dst, nColor, nOpacity);
00188 dst++;
00189 }
00190
00191 dst += width-w0;
00192 }
00193 }
00194 }
00195
00196
00197 void
00198 Image::drawLine(int x1, int y1, int x2, int y2, int r, int g, int b)
00199 {
00200 drawLine(x1,y1, x2,y2, ImageTool::convertPixel24To16(r, g, b));
00201 }
00202
00203 void
00204 Image::drawLine(int x1, int y1, int x2, int y2, unsigned short color)
00205 {
00206 int x=x1, y=y1;
00207 int dx, dy;
00208 int incx, incy;
00209 int balance;
00210
00211 if(x2 >= x1)
00212 { dx = x2 - x1; incx = 1; }
00213 else
00214 { dx = x1 - x2; incx = -1; }
00215
00216 if (y2 >= y1)
00217 { dy = y2 - y1; incy = 1; }
00218 else
00219 { dy = y1 - y2; incy = -1; }
00220
00221 int offset = y*width + x,
00222 incxBuf = incx,
00223 incyBuf = incy*width;
00224
00225 unsigned short* pixels = getPixels();
00226
00227 if(dx==0 && dy==0)
00228 {
00229 pixels[offset] = color;
00230 return;
00231 }
00232
00233 if (dx >= dy)
00234 {
00235 dy <<= 1;
00236 balance = dy - dx;
00237 dx <<= 1;
00238
00239 while (x != x2)
00240 {
00241 pixels[offset] = color;
00242 if (balance >= 0)
00243 {
00244 y += incy; offset += incyBuf;
00245 balance -= dx;
00246 }
00247 balance += dy;
00248 x += incx; offset += incxBuf;
00249 }
00250 pixels[offset] = color;
00251 }
00252 else
00253 {
00254 dx <<= 1;
00255 balance = dx - dy;
00256 dy <<= 1;
00257 while (y != y2)
00258 {
00259 pixels[offset] = color;
00260 if (balance >= 0)
00261 {
00262 x += incx; offset += incxBuf;
00263 balance -= dy;
00264 }
00265 balance += dx;
00266 y += incy; offset += incyBuf;
00267 }
00268 pixels[offset] = color;
00269 }
00270 }
00271
00272
00273 void
00274 Image::setPixel(int x, int y, unsigned short col)
00275 {
00276 unsigned short* pixels = getPixels();
00277 pixels[y*width + x] = col;
00278 }
00279
00280
00281 void
00282 Image::setPixel(int x, int y, int r, int g, int b)
00283 {
00284 unsigned short* pixels = getPixels();
00285 pixels[y*width + x] = ImageTool::convertPixel24To16(r, g, b);
00286 }
00287
00288 Image* Image::createFromPixelBuffer(int nWidth, int nHeight, unsigned short* nPixels, bool nOwner)
00289 {
00290 if(nOwner && nPixels==NULL)
00291 nPixels = new unsigned short[nWidth*nHeight];
00292 return new Image(nWidth, nHeight, nPixels, nOwner);
00293 }
00294
00295
00296 void Image::setPixels(int nWidth, int nHeight, unsigned short* nPixels, bool nPixelsOwner)
00297 {
00298 if( pixelsOwner )
00299 delete pixels;
00300
00301 width = nWidth;
00302 height = nHeight;
00303 pixels = nPixels;
00304 pixelsOwner = nPixelsOwner;
00305 }
00306
00307
00308 }