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 }