Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

SFontLoader.cpp

00001 //Licence: LGPL 00002 //Copyright: Visti Andresen 00003 00004 #include "SFontLoader.h" 00005 00006 #include <iostream> 00007 #include <fstream> 00008 00009 using namespace std; 00010 00011 00012 SFontLoader::SFontLoader() 00013 { 00014 fontData_ = 0; 00015 alphaR_ = 0; 00016 alphaG_ = 0; 00017 alphaB_ = 0; 00018 alphaType_ = GREY_COLOUR; 00019 seperatorR_ = 255; 00020 seperatorG_ = 0; 00021 seperatorB_ = 255; 00022 fontDefinition_ = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"; 00023 for (int i=0; i<256; i++){ 00024 fontGfxTiles[i] = 0; 00025 charWidth_[i] = -1; 00026 } 00027 } 00028 00029 SFontLoader::~SFontLoader() 00030 { 00031 unloadGfx(); 00032 } 00033 00034 00035 void SFontLoader::loadFont(const string &name) 00036 { 00037 unloadGfx(); 00038 00039 fontData_ = loadPpm(name, fontDataWidth_, fontDataHeight_); 00040 00041 for (int i=0; i<256; i++){ 00042 fontGfxTiles[i] = 0; 00043 charWidth_[i] = -1; 00044 } 00045 00046 00047 if (fontData_ !=0){ 00048 findCellSizes(); 00049 00050 numberOfCharsInFont_ = fontDefinition_.size(); 00051 00052 unsigned char *fontDataBuffer = fontData_; 00053 00054 while(isSpaceColour(fontDataBuffer)){ 00055 fontDataBuffer+=4; 00056 } 00057 findCharWidths(fontDataBuffer); 00058 00059 for (unsigned int i = 0; i!=fontDefinition_.size(); i++){ 00060 unsigned char character = (unsigned char)fontDefinition_[i]; 00061 charWidth_[character] = definitionFontWidths_[i]; 00062 00063 fontGfxTiles[character] = 00064 (unsigned char*)malloc(fontCellWidth_*fontCellHeight_*4); 00065 if (fontGfxTiles[character]==0) throw 00066 string("Failed to reserve memory for font data buffer"); 00067 00068 loadCharacter(i, fontDataBuffer, fontGfxTiles[character]); 00069 00070 } 00071 } 00072 else throw string("Failed to open font image: ")+name; 00073 00074 } 00075 00076 void SFontLoader::findCharWidths(unsigned char *result) 00077 { 00078 for (int i = 0; i != numberOfCharsInFont_; i++){ 00079 definitionFontWidths_[i] = 0; 00080 while(!isSpaceColour(result)){ 00081 result+=4; 00082 definitionFontWidths_[i]++; 00083 } 00084 while(isSpaceColour(result)){ 00085 result+=4; 00086 } 00087 definitionFontWidths_[i]--; 00088 00089 } 00090 00091 } 00092 00093 void SFontLoader::loadCharacter(unsigned char number, 00094 unsigned char *inputData, 00095 unsigned char *outputData) 00096 { 00097 00098 for (int i = 0; i != number; i++){ 00099 while(!isSpaceColour(inputData)){ 00100 inputData+=4; 00101 } 00102 while(isSpaceColour(inputData)){ 00103 inputData+=4; 00104 } 00105 } 00106 inputData += fontDataWidth_*4; 00107 00108 memset(outputData, 0, fontCellHeight_*fontCellWidth_*4); 00109 00110 00111 unsigned char *inputBuffer = inputData; 00112 unsigned char *outputBuffer = outputData; 00113 int width = (int)definitionFontWidths_[number]; 00114 //cout << "p" << fontDataHeight_ << "O" << width << endl; 00115 for (int y=0; y != fontDataHeight_-1; y++){ 00116 for (int x=0; x != width; x++){ 00117 *outputBuffer = inputBuffer[0]; 00118 outputBuffer++; 00119 *outputBuffer = inputBuffer[1]; 00120 outputBuffer++; 00121 *outputBuffer = inputBuffer[2]; 00122 outputBuffer++; 00123 *outputBuffer = inputBuffer[3]; 00124 outputBuffer++; 00125 inputBuffer+=4; 00126 } 00127 inputData += fontDataWidth_*4; 00128 inputBuffer = inputData; 00129 outputBuffer = outputData + fontCellWidth_*4*(y+1); 00130 } 00131 } 00132 00133 void SFontLoader::readNumber(ifstream &file, int &number) 00134 { 00135 char c[1]; 00136 00137 file.read((char*)c,1); 00138 while ((*c<'0' || *c>'9') && !file.bad()){ 00139 file.read((char*)c,1); 00140 } 00141 number =0; 00142 while ((*c>='0' && *c<='9') && !file.bad()){ 00143 number = number *10 +*c-'0'; 00144 file.read((char*)c,1); 00145 } 00146 } 00147 00148 unsigned char *SFontLoader::loadPpm(const string &fileName, int &width, 00149 int &height) 00150 { 00151 unsigned char *result=0, *buf; 00152 unsigned char id[5]; 00153 int scale=0; 00154 long count; 00155 ifstream infile (fileName.c_str(), ifstream::binary); 00156 if (!infile) throw string("File IO error, could not open ppm file: ") 00157 +fileName; 00158 infile.read((char*)id,2); 00159 //cout << "starting load of " <<id[0]<<id[1]<<endl; 00160 if (id[0]=='P' || id[1]=='6') { 00161 readNumber(infile, width); 00162 readNumber(infile, height); 00163 readNumber(infile, scale); 00164 cout <<"'"<< width <<"'"<< height<<"'"<<scale<<endl; 00165 00166 if (scale==255){ 00167 result = (unsigned char*)malloc(width*height*4); 00168 if (result!=0){ 00169 buf=result; 00170 for (count=0; count != width*height; count++){ 00171 if (infile.bad()) throw string("File IO error"); 00172 00173 id[0] =10; 00174 id[1] =10; 00175 id[2] =10; 00176 00177 infile.read((char*)id,3); 00178 if(infile.gcount() != 3 || infile.eof()) 00179 throw string("Read error in PPM file."); 00180 buf[0] = id[0]; 00181 buf[1] = id[1]; 00182 buf[2] = id[2]; 00183 00184 switch (alphaType_){ 00185 case NONE: 00186 buf[3] = 255; 00187 break; 00188 case BLACK_MASK: 00189 if (id[0] == 0 && id[1] == 0 && id[2] == 0){ 00190 buf[3] = 0; 00191 } 00192 else { 00193 buf[3]= 255; 00194 } 00195 break; 00196 case GREY_COLOUR: 00197 unsigned int alpha; 00198 alpha = id[0] + id[1] + id[2]; 00199 alpha /= 3; 00200 buf[3] = (unsigned char)alpha; 00201 } 00202 buf+=4; 00203 00204 } 00205 } 00206 else throw string ("Out of memory"); 00207 } 00208 else { 00209 throw string ( 00210 "SFontloader ppm load only supports ppm images with 256 colours per channel" 00211 ); 00212 } 00213 } 00214 infile.close(); 00215 //memset(result, 255, 64*64*4); 00216 return result; 00217 } 00218 00219 00220 void SFontLoader::findCellSizes() 00221 { 00222 int largestWidth=0; 00223 int currentWidth=0; 00224 unsigned char *fontData = fontData_+4; 00225 for (int i=1; i<fontDataWidth_-1; i++){ 00226 if (!isSpaceColour(fontData)){ 00227 currentWidth++; 00228 if (currentWidth > largestWidth){ 00229 largestWidth = currentWidth; 00230 } 00231 } 00232 else currentWidth=0; 00233 fontData+=4; 00234 } 00235 00236 fontCellHeight_ = 1; 00237 while (fontCellHeight_ < fontDataHeight_-1){ 00238 fontCellHeight_*=2; 00239 } 00240 fontCellWidth_ = 1; 00241 while (fontCellWidth_ < largestWidth){ 00242 fontCellWidth_*=2; 00243 } 00244 } 00245 00246 void SFontLoader::unloadGfx() 00247 { 00248 if (fontData_ != 0){ 00249 free (fontData_); 00250 fontData_ = 0; 00251 } 00252 00253 for (int i=0; i<256; i++){ 00254 if (fontGfxTiles[i] != 0){ 00255 free (fontGfxTiles[i]); 00256 fontGfxTiles[i] = 0; 00257 } 00258 charWidth_[i] = -1; 00259 } 00260 } 00261 00262 unsigned char *SFontLoader::getDataForCharacter(char character) 00263 { 00264 return fontGfxTiles[(unsigned char) character]; 00265 } 00266 00267 int SFontLoader::getCharacterWidth(char character) 00268 { 00269 return charWidth_[(unsigned char) character]; 00270 }

Generated on Wed Sep 1 14:46:57 2004 by doxygen 1.3.7