image.cpp

Go to the documentation of this file.
00001 /******************************************************************************
00002  *
00003  * $Id: image.cpp,v 1.14 2001/03/19 19:27:40 root Exp $
00004  *
00005  *
00006  * Copyright (C) 1997-2008 by Dimitri van Heesch.
00007  *
00008  * Permission to use, copy, modify, and distribute this software and its
00009  * documentation under the terms of the GNU General Public License is hereby 
00010  * granted. No representations are made about the suitability of this software 
00011  * for any purpose. It is provided "as is" without express or implied warranty.
00012  * See the GNU General Public License for more details.
00013  *
00014  * Documents produced by Doxygen are derivative works derived from the
00015  * input used in their production; they are not affected by this license.
00016  *
00017  */
00018 
00019 #include "qtbc.h"
00020 #include "image.h"
00021 #include "pngenc.h"
00022 #include <qglobal.h>
00023 
00024 const int charSetWidth=80;
00025 const int charHeight=12;
00026 const int numChars=96;
00027 
00028 unsigned short charPos[numChars]    = 
00029   {   
00030       0,  5,  8, 13, 20, 27, 38, 47, 
00031      50, 54, 58, 65, 72, 76, 83, 87, 
00032      91, 98,105,112,119,126,133,140,
00033     147,154,161,164,167,174,181,188,
00034     195,207,216,224,233,242,250,258,
00035     267,276,279,286,294,301,312,321,
00036     331,339,349,357,365,372,380,389,
00037     400,409,418,427,430,434,437,443,
00038     450,453,460,467,474,481,488,492,
00039     499,506,509,512,518,521,530,537,
00040     544,551,557,562,568,571,578,585,
00041     594,600,607,613,617,620,624,631
00042   };
00043 
00044 unsigned char charWidth[numChars] = 
00045   {
00046      5, 3, 5, 7, 7,11, 9, 3,
00047      4, 4, 7, 7, 4, 7, 4, 4,
00048 
00049      7, 7, 7, 7, 7, 7, 7, 7,
00050      7, 7, 3, 3, 7, 7, 7, 7,
00051     12, 9, 8, 9, 9, 8, 8, 9,
00052      9, 3, 7, 8, 7,11, 9,10,
00053      8,10, 8, 8, 7, 8, 9,11,
00054      9, 9, 9, 3, 4, 3, 6, 7,
00055      3, 7, 7, 7, 7, 7, 4, 7,
00056      7, 3, 3, 6, 3, 9, 7, 7,
00057      7, 6, 5, 6, 3, 7, 7, 9,
00058      6, 7, 6, 4, 3, 4, 7, 5   
00059   };
00060 
00061 unsigned char fontRaw[charSetWidth*charHeight] = {
00062   0x02, 0x50, 0x01, 0x06, 0x20, 0x60, 0xc6, 0x04, 0x00, 0x00, 0x00, 0x27,
00063   0x04, 0x1c, 0x38, 0x11, 0xf1, 0xc7, 0xc7, 0x0e, 0x00, 0x00, 0x00, 0x03,
00064   0x81, 0xf0, 0x10, 0x7c, 0x1e, 0x3e, 0x1f, 0x9f, 0x87, 0x88, 0x24, 0x09,
00065   0x09, 0x02, 0x02, 0x41, 0x0f, 0x0f, 0x83, 0xc3, 0xe1, 0xe7, 0xf4, 0x24,
00066   0x12, 0x22, 0x41, 0x20, 0x9f, 0xce, 0x30, 0x00, 0x10, 0x04, 0x00, 0x01,
00067   0x00, 0x30, 0x08, 0x12, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40,
00068   0x00, 0x00, 0x00, 0x00, 0x01, 0xac, 0x00, 0x00, 0x02, 0x51, 0x43, 0x89,
00069   0x40, 0x90, 0x49, 0x15, 0x00, 0x00, 0x00, 0x28, 0x9c, 0x22, 0x44, 0x31,
00070   0x02, 0x20, 0x48, 0x91, 0x00, 0x00, 0x00, 0x04, 0x46, 0x08, 0x28, 0x42,
00071   0x21, 0x21, 0x10, 0x10, 0x08, 0x48, 0x24, 0x09, 0x11, 0x03, 0x06, 0x61,
00072   0x10, 0x88, 0x44, 0x22, 0x12, 0x10, 0x84, 0x24, 0x12, 0x22, 0x22, 0x20,
00073   0x80, 0x4a, 0x11, 0x00, 0x20, 0x04, 0x00, 0x01, 0x00, 0x40, 0x08, 0x00,
00074   0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00,
00075   0x02, 0x22, 0x00, 0x00, 0x02, 0x51, 0x45, 0x49, 0x40, 0x90, 0x89, 0x0a,
00076   0x00, 0x00, 0x00, 0x48, 0x84, 0x02, 0x04, 0x51, 0x02, 0x00, 0x88, 0x91,
00077   0x00, 0x00, 0x00, 0x04, 0x44, 0xd4, 0x28, 0x42, 0x40, 0x20, 0x90, 0x10,
00078   0x10, 0x08, 0x24, 0x09, 0x21, 0x03, 0x06, 0x51, 0x20, 0x48, 0x48, 0x12,
00079   0x12, 0x00, 0x84, 0x22, 0x22, 0x22, 0x22, 0x11, 0x00, 0x89, 0x12, 0x80,
00080   0x31, 0xc5, 0x87, 0x0d, 0x1c, 0xe3, 0x4b, 0x12, 0x49, 0x29, 0x16, 0x1c,
00081   0x58, 0x69, 0x4c, 0xe8, 0x91, 0x44, 0x61, 0x44, 0xf2, 0x22, 0x00, 0x00,
00082   0x02, 0x07, 0xe5, 0x06, 0x80, 0x60, 0x10, 0x95, 0x08, 0x00, 0x00, 0x48,
00083   0x84, 0x04, 0x18, 0x51, 0xe2, 0xc0, 0x87, 0x11, 0x24, 0x18, 0x03, 0x00,
00084   0x89, 0x24, 0x44, 0x42, 0x40, 0x20, 0x90, 0x10, 0x10, 0x08, 0x24, 0x09,
00085   0x41, 0x02, 0x8a, 0x51, 0x20, 0x48, 0x48, 0x12, 0x11, 0x80, 0x84, 0x22,
00086   0x21, 0x24, 0x14, 0x11, 0x01, 0x09, 0x14, 0x40, 0x02, 0x26, 0x48, 0x93,
00087   0x22, 0x44, 0xcc, 0x92, 0x51, 0x36, 0x99, 0x22, 0x64, 0x99, 0x92, 0x48,
00088   0x91, 0x44, 0x52, 0x44, 0x12, 0x22, 0x00, 0x00, 0x02, 0x01, 0x43, 0x80,
00089   0x80, 0xa0, 0x10, 0x84, 0x08, 0x00, 0x00, 0x88, 0x84, 0x08, 0x04, 0x90,
00090   0x13, 0x21, 0x08, 0x8f, 0x00, 0x61, 0xf0, 0xc0, 0x8a, 0x24, 0x44, 0x7c,
00091   0x40, 0x20, 0x9f, 0x9f, 0x11, 0xcf, 0xe4, 0x09, 0xc1, 0x02, 0x8a, 0x49,
00092   0x20, 0x4f, 0x88, 0x13, 0xe0, 0x60, 0x84, 0x22, 0x21, 0x54, 0x08, 0x0a,
00093   0x02, 0x08, 0x90, 0x00, 0x00, 0x24, 0x48, 0x11, 0x22, 0x44, 0x48, 0x92,
00094   0x61, 0x24, 0x91, 0x22, 0x44, 0x89, 0x10, 0x48, 0x91, 0x24, 0x8c, 0x44,
00095   0x22, 0x22, 0x64, 0x00, 0x02, 0x07, 0xe1, 0x41, 0x31, 0x14, 0x10, 0x80,
00096   0x3e, 0x07, 0xc0, 0x88, 0x84, 0x10, 0x05, 0x10, 0x12, 0x21, 0x08, 0x81,
00097   0x01, 0x80, 0x00, 0x31, 0x0a, 0x24, 0x7c, 0x42, 0x40, 0x20, 0x90, 0x10,
00098   0x10, 0x48, 0x24, 0x09, 0x21, 0x02, 0x52, 0x45, 0x20, 0x48, 0x08, 0x92,
00099   0x20, 0x10, 0x84, 0x21, 0x41, 0x54, 0x14, 0x04, 0x04, 0x08, 0x90, 0x00,
00100   0x01, 0xe4, 0x48, 0x11, 0x3e, 0x44, 0x48, 0x92, 0x61, 0x24, 0x91, 0x22,
00101   0x44, 0x89, 0x0c, 0x48, 0x8a, 0x24, 0x8c, 0x48, 0x44, 0x21, 0x98, 0x00,
00102   0x02, 0x02, 0x85, 0x41, 0x49, 0x08, 0x10, 0x80, 0x08, 0x00, 0x00, 0x88,
00103   0x84, 0x20, 0x45, 0xf9, 0x12, 0x21, 0x08, 0x81, 0x00, 0x61, 0xf0, 0xc1,
00104   0x0a, 0x68, 0x82, 0x42, 0x40, 0x20, 0x90, 0x10, 0x10, 0x48, 0x24, 0x89,
00105   0x11, 0x02, 0x52, 0x45, 0x20, 0x48, 0x08, 0x52, 0x12, 0x10, 0x84, 0x21,
00106   0x40, 0x88, 0x22, 0x04, 0x08, 0x08, 0x90, 0x00, 0x02, 0x24, 0x48, 0x11,
00107   0x20, 0x44, 0x48, 0x92, 0x51, 0x24, 0x91, 0x22, 0x44, 0x89, 0x02, 0x48,
00108   0x8a, 0x2a, 0x92, 0x28, 0x42, 0x22, 0x00, 0x00, 0x00, 0x02, 0x85, 0x41,
00109   0x49, 0x18, 0x10, 0x80, 0x08, 0x00, 0x01, 0x08, 0x84, 0x20, 0x44, 0x11,
00110   0x12, 0x22, 0x08, 0x91, 0x00, 0x18, 0x03, 0x00, 0x09, 0xb0, 0x82, 0x42,
00111   0x21, 0x21, 0x10, 0x10, 0x08, 0xc8, 0x24, 0x89, 0x09, 0x02, 0x22, 0x43,
00112   0x10, 0x88, 0x04, 0x22, 0x12, 0x10, 0x84, 0x20, 0x80, 0x88, 0x22, 0x04,
00113   0x10, 0x08, 0x50, 0x00, 0x02, 0x26, 0x48, 0x93, 0x22, 0x44, 0xc8, 0x92,
00114   0x49, 0x24, 0x91, 0x22, 0x64, 0x99, 0x12, 0x49, 0x84, 0x11, 0x21, 0x28,
00115   0x82, 0x22, 0x00, 0x00, 0x02, 0x02, 0x83, 0x82, 0x30, 0xe4, 0x10, 0x80,
00116   0x00, 0x20, 0x05, 0x07, 0x04, 0x3e, 0x38, 0x10, 0xe1, 0xc2, 0x07, 0x0e,
00117   0x24, 0x00, 0x00, 0x01, 0x04, 0x00, 0x82, 0x7c, 0x1e, 0x3e, 0x1f, 0x90,
00118   0x07, 0x48, 0x24, 0x71, 0x05, 0xf2, 0x22, 0x41, 0x0f, 0x08, 0x03, 0xd2,
00119   0x11, 0xe0, 0x83, 0xc0, 0x80, 0x88, 0x41, 0x04, 0x1f, 0xc8, 0x50, 0x00,
00120   0x01, 0xd5, 0x87, 0x0d, 0x1c, 0x43, 0x48, 0x92, 0x45, 0x24, 0x91, 0x1c,
00121   0x58, 0x69, 0x0c, 0x66, 0x84, 0x11, 0x21, 0x10, 0xf2, 0x22, 0x00, 0x00,
00122   0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x20, 0x00, 0x00,
00123   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
00124   0x03, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00125   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00126   0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
00127   0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00,
00128   0x00, 0x00, 0x00, 0x10, 0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00129   0x00, 0x00, 0x09, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00130   0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00131   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00132   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00133   0x00, 0x08, 0x10, 0x1f, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x04, 0x40, 0x02,
00134   0x00, 0x00, 0x00, 0x00, 0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20,
00135   0x02, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00,
00136   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00137   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00138   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00139   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00,
00140   0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x80, 0x04, 0x00, 0x00, 0x00, 0x00,
00141   0x40, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0xac, 0x00, 0x00
00142 };
00143 
00144 static Color palette[] =
00145 {
00146   { 0xff, 0xff, 0xff },
00147   { 0x00, 0x00, 0x00 },
00148   { 0xff, 0xff, 0xc0 },
00149   { 0x9f, 0x9f, 0x60 },
00150   { 0x90, 0x00, 0x00 },
00151   { 0x00, 0x90, 0x00 },
00152   { 0x00, 0x00, 0x90 },
00153   { 0xc0, 0xc0, 0xc0 }
00154 };
00155 
00156 static Color palette2[] =
00157 {
00158   { 0xff, 0xff, 0xff },
00159   { 0xe0, 0xe0, 0xe0 },
00160   { 0xd0, 0xd0, 0xd0 },
00161   { 0xc0, 0xc0, 0xc0 },
00162   { 0xb0, 0xb0, 0xb0 },
00163   { 0xa0, 0xa0, 0xa0 },
00164   { 0x90, 0x90, 0x90 },
00165   { 0x80, 0x80, 0x80 },
00166   { 0x70, 0x70, 0x70 },
00167   { 0x60, 0x60, 0x60 },
00168   { 0x50, 0x50, 0x50 },
00169   { 0x40, 0x40, 0x40 },
00170   { 0x30, 0x30, 0x30 },
00171   { 0x20, 0x20, 0x20 },
00172   { 0x10, 0x10, 0x10 },
00173   { 0x00, 0x00, 0x00 }
00174 };
00175 
00176 Image::Image(int w,int h)
00177 {
00178   data = new uchar[w*h];
00179   memset(data,0,w*h);
00180   width = w;
00181   height = h;
00182 }
00183 
00184 Image::~Image()
00185 {
00186   delete[] data;
00187 }
00188 
00189 void Image::setPixel(int x,int y,uchar val)
00190 {
00191   if (x>=0 && x<width && y>=0 && y<height)
00192     data[y*width+x] = val;
00193 }
00194 
00195 uchar Image::getPixel(int x,int y) const
00196 {
00197   if (x>=0 && x<width && y>=0 && y<height)
00198     return data[y*width+x];
00199   else
00200     return 0;
00201 }
00202 
00203 void Image::writeChar(int x,int y,char c,uchar fg) 
00204 {
00205   if (c>=' ')
00206   {
00207     int xf,yf,ci=c-' ';
00208     int rowOffset=0;
00209     int cw = charWidth[ci];
00210     int cp = charPos[ci];
00211     for (yf=0;yf<charHeight;yf++)
00212     {
00213       unsigned short bitPattern=0;
00214       int bitsLeft=cw;
00215       int byteOffset = rowOffset+(cp>>3);
00216       int bitOffset  = cp&7;
00217       // get the bit pattern for row yf of the character from the font data
00218       while (bitsLeft>0)
00219       {
00220         int bits=8-bitOffset;
00221         if (bits>bitsLeft) bits=bitsLeft; 
00222         bitPattern<<=bits; 
00223         bitPattern|=((fontRaw[byteOffset]<<bitOffset)&0xff)>>(8-bits);
00224         bitsLeft-=bits;
00225         bitOffset=0;
00226         byteOffset++;
00227       }
00228       int mask=1<<(cw-1);
00229       // draw character row yf
00230       for (xf=0;xf<cw;xf++)
00231       {
00232         setPixel(x+xf,y+yf,(bitPattern&mask) ? fg : getPixel(x+xf,y+yf));
00233         mask>>=1;
00234       }
00235       rowOffset+=charSetWidth;
00236     }
00237   } 
00238 }
00239 
00240 void Image::writeString(int x,int y,const char *s,uchar fg) 
00241 {
00242   if (s)
00243   {
00244     char c;
00245     while ((c=*s++))
00246     {
00247       writeChar(x,y,c,fg);
00248       x+=charWidth[c-' '];
00249     }
00250   }
00251 }
00252 
00253 uint Image::stringLength(const char *s) 
00254 {
00255   int w=0;
00256   if (s)
00257   {
00258     char c;
00259     while ((c=*s++)) w+=charWidth[c-' '];
00260   }
00261   return w;
00262 }
00263 
00264 void Image::drawHorzLine(int y,int xs,int xe,uchar colIndex,uint mask)
00265 {
00266   int x,i=0,j=0;
00267   for (x=xs;x<=xe;x++,j++) 
00268   {
00269     if (j&1) i++;
00270     if (mask&(1<<(i&0x1f))) setPixel(x,y,colIndex);
00271   }
00272 } 
00273 
00274 void Image::drawHorzArrow(int y,int xs,int xe,uchar colIndex,uint mask)
00275 {
00276   drawHorzLine(y,xs,xe,colIndex,mask);
00277   int i;
00278   for (i=0;i<6;i++)
00279   {
00280     int h=i>>1;
00281     drawVertLine(xe-i,y-h,y+h,colIndex,0xffffffff);
00282   }
00283 } 
00284 
00285 void Image::drawVertLine(int x,int ys,int ye,uchar colIndex,uint mask)
00286 {
00287   int y,i=0;
00288   for (y=ys;y<=ye;y++,i++) 
00289   {
00290     if (mask&(1<<(i&0x1f))) setPixel(x,y,colIndex);
00291   }
00292 }
00293 
00294 void Image::drawVertArrow(int x,int ys,int ye,uchar colIndex,uint mask)
00295 {
00296   drawVertLine(x,ys,ye,colIndex,mask);
00297   int i;
00298   for (i=0;i<6;i++)
00299   {
00300     int h=i>>1;
00301     drawHorzLine(ys+i,x-h,x+h,colIndex,0xffffffff);
00302   }
00303 }
00304 
00305 void Image::drawRect(int x,int y,int w,int h,uchar colIndex,uint mask)
00306 {
00307   drawHorzLine(y,x,x+w-1,colIndex,mask);
00308   drawHorzLine(y+h-1,x,x+w-1,colIndex,mask);
00309   drawVertLine(x,y,y+h-1,colIndex,mask);
00310   drawVertLine(x+w-1,y,y+h-1,colIndex,mask);
00311 }
00312 
00313 void Image::fillRect(int x,int y,int lwidth,int lheight,uchar colIndex,uint mask)
00314 {
00315   int xp,yp,xi,yi;
00316   for (yp=y,yi=0;yp<y+lheight;yp++,yi++)
00317     for (xp=x,xi=0;xp<x+lwidth;xp++,xi++)
00318       if (mask&(1<<((xi+yi)&0x1f))) 
00319         setPixel(xp,yp,colIndex);
00320 }
00321 
00322 bool Image::save(const char *fileName,int mode)
00323 {
00324   PngEncoder enc(data,
00325                  mode==0 ? palette : palette2,
00326                  width,height,
00327                  mode==0 ? 3 : 4,
00328                   0);
00329   enc.write(fileName);
00330   return TRUE;
00331 }



Generated on Mon Mar 31 10:58:39 2008 by  doxygen 1.5.1