Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

font_description.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: font_description.cpp,v 1.3 2001/03/19 13:48:26 sphair Exp $
00003 
00004         ------------------------------------------------------------------------
00005         ClanLib, the platform independent game SDK.
00006 
00007         This library is distributed under the GNU LIBRARY GENERAL PUBLIC LICENSE
00008         version 2. See COPYING for details.
00009 
00010         For a total list of contributers see CREDITS.
00011 
00012         ------------------------------------------------------------------------
00013 
00014         File purpose:
00015                 Simple font support.
00016 */
00017 
00018 #include "Core/precomp.h"
00019 #include "Display/Display/Generic/pixeldata.h"
00020 #include "API/Display/SurfaceProviders/sprite_subarray_provider.h"
00021 #include "API/Core/System/error.h"
00022 #include "API/Display/SurfaceProviders/sprite2.h"
00023 #include "API/Core/IOData/inputsource.h"
00024 #include "API/Display/Font/font_description.h"
00025 
00026 CL_Font_Description::CL_Font_Description(CL_InputSource *input)
00027 : source(NULL)
00028 {
00029         space_len = input->read_int32();
00030         subtract_width = input->read_int32();
00031         letters = input->read_string();
00032         
00033         int len = letters.length();
00034         for (int i=0; i<len; i++)
00035         {
00036                 letter_providers.push_back(new CL_Sprite2Provider(input));
00037         }
00038 }
00039 
00040 CL_Font_Description::CL_Font_Description(
00041         CL_SurfaceProvider *p,
00042         int x, int y,
00043         int *tcols, int num_tcols,
00044         int spacelen,
00045         int subtract_width,
00046         const char *letters)
00047 {
00048         // this constructor handles the _old_ pcx font system.
00049 
00050         this->source = p;
00051         this->space_len = spacelen;
00052         this->subtract_width = subtract_width;
00053         this->letters = letters;
00054                 
00055         p->lock();
00056 
00057         if (p->get_depth() != 8)
00058         {
00059                 p->unlock();
00060                 throw CL_Error("Old font method only works on PAL8 images.");
00061         }
00062                 
00063         unsigned char *surface_data = (unsigned char *) p->get_data();
00064 
00065         // Find height
00066         unsigned int h;
00067         for (h=y; h<p->get_height(); h++)
00068         {
00069                 if (surface_data[h*p->get_pitch()+x]==255)
00070                 {
00071                         h-=y;
00072                         break;
00073                 }
00074         }
00075         
00076         // Load letters
00077         int org_x=x;
00078         int next_line=0;
00079         int pos=0;
00080         unsigned char bogst_nr=0;
00081 
00082         bogst_nr=letters[pos];
00083                 
00084         while (bogst_nr != 0)
00085         {
00086                 // Find width
00087                 int b;
00088                 int p_width = p->get_width();
00089                 for (b=x; b<p_width; b++)
00090                 {
00091                         if (surface_data[y*p->get_pitch()+b]==254)
00092                         {
00093                                 b-=x;
00094                                 break;
00095                         }
00096                         else if (surface_data[y*p->get_pitch()+b]==253)
00097                         {
00098                                 b-=x;
00099                                 next_line=-1;
00100                                 break;
00101                         }
00102                 }
00103 
00104                 letter_providers.push_back(
00105                 new CL_Sprite2Provider(
00106                         p,
00107                         x, y,
00108                         b, h,
00109                         tcols, num_tcols));
00110                 x+=b+1;
00111 
00112                 if (next_line)
00113                 {
00114                         x=org_x;
00115                         y+=h+1;
00116                         next_line=0;
00117                 }
00118 
00119                 pos++;
00120                 bogst_nr=letters[pos];
00121         }
00122 
00123         p->unlock();
00124 }
00125 
00126 CL_Font_Description::CL_Font_Description(
00127         CL_SurfaceProvider *source,
00128         float trans_limit,
00129         int space_len,
00130         int subtract_width,
00131         const char *letters)
00132 {
00133         this->source = source;
00134         this->space_len = space_len;
00135         this->subtract_width = subtract_width;
00136         this->letters = letters;
00137 
00138         int begin=0;
00139         bool prev_trans=true;
00140                 
00141         CL_PixelData alpha(0, 0, 0, 255, source, 1);
00142 
00143         int *opaque_row = new int[alpha.get_width()];
00144         memset(opaque_row, 0, alpha.get_width()*sizeof(int));
00145 
00146         int alpha_width = alpha.get_width();
00147         int alpha_height = alpha.get_height();
00148         bool found_opaque = false;
00149         bool found_trans = false;
00150                 
00151         int cut_top = 0;
00152         int cut_bottom = alpha_height;
00153                 
00154         for (int y=0; y < alpha_height; y++)
00155         {
00156                 bool opaque_line = false;
00157                 unsigned char *line = alpha.get_line_pixel(y);
00158                 for (int x=0; x < alpha_width; x++)
00159                 {
00160                         if (line[x] > trans_limit*255)
00161                         {
00162                                 opaque_row[x] = 1;
00163                                 opaque_line = true;
00164                                 found_opaque = true;
00165                         }
00166                 }
00167                         
00168                 if (opaque_line == false) // cut something of top or bottom
00169                 {
00170                         if (found_opaque)
00171                         {
00172                                 cut_bottom--;
00173                                 found_trans = true;
00174                         }
00175                         else
00176                                 cut_top ++;
00177                 }
00178                 else if (found_trans)
00179                 {
00180                         found_trans = false;
00181                         cut_bottom = alpha_height;
00182                 }
00183         }
00184                 
00185         if (cut_top >= cut_bottom)
00186                 throw CL_Error("Font image contained only alpha! (or the alpha clipper is broken)");
00187 
00188         for(int x=0; x < alpha_width; x++)
00189         {
00190                 if(opaque_row[x] && prev_trans)
00191                 {
00192                         begin = x;
00193                         prev_trans = false;
00194                 }
00195                 else if (!opaque_row[x] && !prev_trans)
00196                 {
00197                         letter_providers.push_back(
00198                                 new CL_SpriteSubarrayProvider(
00199                                         source,
00200                                         begin,
00201                                         cut_top,
00202                                         x-begin+1,
00203                                         cut_bottom-cut_top,
00204                                         1, 1));
00205 
00206                         prev_trans = true;
00207                 }
00208         }
00209                 
00210         if (!prev_trans)
00211         {
00212                 letter_providers.push_back(
00213                         new CL_SpriteSubarrayProvider(
00214                                 source,
00215                                 begin,
00216                                 cut_top,
00217                                 alpha.get_width()-begin,
00218                                 cut_bottom-cut_top,
00219                                 1, 1));
00220         }
00221 
00222         delete opaque_row;
00223 
00224         // if you get this assertion, then it is because you have more or
00225         // less letters in your font than in your font description.
00226         if(letter_providers.size() != this->letters.size())
00227         {
00228                 std::cout <<
00229                         "Resourcefile characters: " <<
00230                         letter_providers.size() <<
00231                         " Imagefile characters: " <<
00232                         this->letters.size() <<
00233                         std::endl;
00234         }
00235         cl_assert(letter_providers.size() == this->letters.size());
00236 }
00237 
00238 void CL_Font_Description::lock()
00239 {
00240         if (source != NULL) source->lock();
00241 }
00242 
00243 void CL_Font_Description::unlock()
00244 {
00245         if (source != NULL) source->unlock();
00246 }

Generated at Wed Apr 4 19:54:00 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001