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

resourcetype_font.cpp

Go to the documentation of this file.
00001 /*
00002         $Id: resourcetype_font.cpp,v 1.1 2001/03/06 15:09:20 mbn 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                 Font resource type
00016 
00017 */
00018 
00019 #include "Core/precomp.h"
00020 
00021 #include <API/Core/System/cl_assert.h>
00022 #include <API/Core/System/error.h>
00023 #include <API/Display/Font/font_description.h>
00024 #include <API/Display/Font/font.h>
00025 #include <API/Display/Display/surfaceprovider.h>
00026 #include <API/Display/Display/palette.h>
00027 #include <Display/Font/resource_font_generic.h>
00028 #include <Display/Font/resourcetype_font.h>
00029 #include <Display/Display/Generic/restype_surface.h>
00030 
00031 /******************************************************************************
00032                                                 class CL_Res_Font
00033 ******************************************************************************/
00034 
00035 CL_Res_Font::CL_Res_Font() : CL_Res_Font_Generic("font")
00036 {
00037 }
00038 
00039 CL_Resource *CL_Res_Font::create_from_location(
00040         std::string name,
00041         std::string location,
00042         CL_ResourceOptions *options,
00043         CL_ResourceManager *parent)
00044 {
00045         CL_String ext = CL_String(location).right(4);
00046         ext.to_lower();
00047 
00048         bool is_font_type = false;
00049         if (options->exists("type")) 
00050         {
00051                 if (options->get_value("type") != "font") return NULL;
00052                 is_font_type = true;
00053         }
00054 
00055         if (is_font_type || options->exists("font"))
00056         {
00057                 return new CL_Font_Resource(
00058                         name,
00059                         location,
00060                         options,
00061                         parent);
00062         }
00063 
00064         return NULL;
00065 }
00066 
00067 CL_Resource *CL_Res_Font::create_from_serialization(
00068         std::string name,
00069         CL_ResourceManager *parent)
00070 {
00071         return new CL_Font_Resource(
00072                 name,
00073                 parent);
00074 }
00075 /******************************************************************************
00076                                                 class CL_Font_Resource
00077 ******************************************************************************/
00078 
00079 CL_Font_Resource::CL_Font_Resource(
00080         std::string name,
00081         std::string location,
00082         CL_ResourceOptions *options,
00083         CL_ResourceManager *parent)
00084 : CL_Font_Resource_Generic("font", name)
00085 {
00086         this->location = location;
00087         this->options = options;
00088         this->parent = parent;
00089         from_datafile = false;
00090         load_count = 0;
00091 
00092         font = NULL;
00093         font_desc = NULL;
00094 }
00095 
00096 CL_Font_Resource::CL_Font_Resource(
00097         std::string name,
00098         CL_ResourceManager *parent)
00099 : CL_Font_Resource_Generic("font", name)
00100 {
00101         location = "";
00102         options = NULL;
00103         this->parent = parent;
00104         from_datafile = true;
00105         load_count = 0;
00106 
00107         font = NULL;
00108         font_desc = NULL;
00109 }
00110 
00111 CL_Font_Resource::~CL_Font_Resource()
00112 {
00113         delete options;
00114 //      delete font_desc;
00115 }
00116 
00117 void CL_Font_Resource::serialize_save(CL_OutputSource *output)
00118 {
00119         load_count++;
00120         if (font_desc != NULL) return; // already loaded.
00121 
00122         if (from_datafile) load_from_datafile();
00123         else load_from_file();
00124 
00125         output->write_int32(font_desc->space_len);
00126         output->write_int32(font_desc->subtract_width);
00127         output->write_string(font_desc->letters.c_str());
00128 /*
00129         output->write_short16(font_desc->letters.length()+1);
00130         output->write(font_desc->letters.c_str(), font_desc->letters.length()+1);
00131 */      
00132         unsigned int len = font_desc->letters.length();
00133         if (len > font_desc->letter_providers.size())
00134         {
00135                 CL_String err;
00136                 err << "Font loading error - ";
00137                 err << "Letters expected:  " << len;
00138                 err << ", letters available: " << CL_String((int)          font_desc->letter_providers.size());
00139                 //This just makes it palatable to the compiler
00140                 throw CL_Error(err.get_string());
00141         }
00142         else if (len < font_desc->letter_providers.size())
00143         {
00144                 std::cout << "ClanLib Font Warning: Font letters do not match!" << std::endl;
00145                 std::cout << "ClanLib Font Warning: Letters expected:  " << len << std::endl;
00146                 std::cout << "ClanLib Font Warning: Letters available: "
00147                         << font_desc->letter_providers.size() << std::endl;
00148         }
00149         
00150         if (len > 0)
00151         {
00152                 font_desc->letter_providers[0]->lock();
00153         }
00154         for(unsigned int i=0; i<len; i++)
00155         {
00156                 CL_SurfaceProvider *provider = font_desc->letter_providers[i];
00157                 cl_assert(provider != NULL);
00158 
00159                 provider->lock();
00160 
00161                 int width = provider->get_width();
00162                 int height = provider->get_height();
00163                 int no_sprs = provider->get_num_frames();
00164                 int bytes_per_pixel = (provider->get_depth()+7)/8;
00165                 int transcol = provider->uses_src_colorkey() ? (int)provider->get_src_colorkey() : -1;
00166 //              int format = provider->get_pixel_format();
00167                 int red_mask = provider->get_red_mask();
00168                 int green_mask = provider->get_green_mask();
00169                 int blue_mask = provider->get_blue_mask();
00170                 int alpha_mask = provider->get_alpha_mask();
00171                 int translate_x = provider->get_translate_x();
00172                 int translate_y = provider->get_translate_y();
00173                 int pitch = provider->get_pitch();
00174 
00175                 CL_Palette *pal = provider->get_palette();
00176                 unsigned char *data = (unsigned char *) provider->get_data();
00177                 cl_assert(data != NULL);
00178 
00179                 output->write_int32(width);
00180                 output->write_int32(height);
00181                 output->write_int32(no_sprs);
00182                 output->write_int32(transcol);
00183                 
00184                 char palette_bool = (pal != NULL) ? 1 : 0;
00185                 output->write_char8(palette_bool);
00186                 
00187                 if (palette_bool) output->write(pal->palette, 256*3);
00188 
00189                 char indexed_bool = (provider->is_indexed()) ? 1 : 0;
00190                 output->write_char8(indexed_bool);
00191                 
00192 //              output->write_int32(format);
00193                 output->write_int32(red_mask);
00194                 output->write_int32(green_mask);
00195                 output->write_int32(blue_mask);
00196                 output->write_int32(alpha_mask);
00197                 output->write_int32(provider->get_depth());
00198 
00199                 if (transcol == -1)
00200                 {
00201                         int bytes_pr_line = width*bytes_per_pixel;
00202                         for (int y=0; y<height*no_sprs; y++)
00203                         {
00204                                 int img_y = y+translate_y;
00205 
00206                                 output->write(
00207                                         data+translate_x*bytes_per_pixel+img_y*pitch,
00208                                         bytes_pr_line);
00209                         }
00210                 }
00211                 else
00212                 {
00213                         for (int y=0; y<height*no_sprs; y++)
00214                         {
00215                                 int img_y = y+translate_y;
00216 
00217                                 output->write(
00218                                         data+translate_x*bytes_per_pixel+img_y*pitch,
00219                                         bytes_per_pixel*width);
00220                         }
00221                 }
00222 
00223                 provider->unlock();
00224         }
00225         if (len > 0)
00226         {
00227                 font_desc->letter_providers[0]->unlock();
00228         }
00229         
00230         unload();
00231 }
00232 
00233 void CL_Font_Resource::load()
00234 {
00235         load_count++;
00236         if (font_desc != NULL) return; // already loaded.
00237 
00238         if (from_datafile) load_from_datafile();
00239         else load_from_file();
00240 
00241         font = new CL_Font(font_desc);
00242 }
00243 
00244 void CL_Font_Resource::unload()
00245 {
00246         load_count--;
00247         if (load_count == 0)
00248         {
00249                 delete font_desc;
00250                 font_desc = NULL;
00251                 delete font;
00252                 font = NULL;
00253         }
00254 }
00255 
00256 /*
00257 CL_Font *CL_Font_Resource::get_font()
00258 {
00259         load();
00260         return font;
00261 }
00262 */
00263 
00264 void CL_Font_Resource::load_from_datafile()
00265 {
00266         CL_InputSourceProvider *provider = parent->get_resource_provider();
00267 
00268         font_desc = new CL_Font_Description(
00269                 provider->open_source(get_name().c_str()));
00270 }
00271 
00272 void CL_Font_Resource::load_from_file()
00273 {
00274         CL_String ext = CL_String(location).right(4);
00275         ext.to_lower();
00276         
00277         // the alphafont options should probally be required to differ
00278         // indexed png's from rgba ones
00279         if (ext == ".tga" || options->exists("alphafont")
00280             || (ext == ".png" && options->exists("alphafont")))
00281         {
00282                 if (options->exists("spacelen") == false)
00283                         throw CL_Error("Font missing spacelen option.");
00284 
00285                 if (options->exists("trans_limit") == false)
00286                         throw CL_Error("Font missing trans_limit option.");
00287 
00288                 if (options->exists("subtract_width") == false)
00289                         throw CL_Error("Font missing subtract_width option.");
00290 
00291                 if (options->exists("letters") == false)
00292                         throw CL_Error("Font missing letters option.");
00293 
00294                 int space_len = CL_String(options->get_value("spacelen")).get_as_int();
00295                 float trans_limit = CL_String(options->get_value("trans_limit")).get_as_float();
00296                 int subtract_width = CL_String(options->get_value("subtract_width")).get_as_int();
00297                 CL_SurfaceProvider* provider = 0;
00298 
00299                 for (std::list<CL_ResourceSource_Surface*>::iterator it = CL_Res_Surface::surface_sources.begin();
00300                      it != CL_Res_Surface::surface_sources.end();
00301                      it++)
00302                 {
00303                         if ((*it)->can_create (ext, options))
00304                         {
00305                                 provider = (*it)->create (location, options, parent);
00306                                 break;
00307                         }
00308                 }
00309                 cl_assert (provider != NULL);
00310 
00311                 font_desc = new CL_Font_Description(provider,
00312                                                     trans_limit,
00313                                                     space_len,
00314                                                     subtract_width,
00315                                                     options->get_value("letters").c_str());
00316         }
00317         else
00318         {
00319                 if (options->exists("x") == false)
00320                         throw CL_Error("Font missing x coordinate option.");
00321 
00322                 if (options->exists("y") == false)
00323                         throw CL_Error("Font missing y coordinate option.");
00324 
00325                 if (options->exists("spacelen") == false)
00326                         throw CL_Error("Font missing spacelen option.");
00327 
00328                 if (options->exists("letters") == false)
00329                         throw CL_Error("Font missing letters option.");
00330 
00331                 int x = CL_String(options->get_value("x")).get_as_int();
00332                 int y = CL_String(options->get_value("y")).get_as_int();
00333                 int space_len = CL_String(options->get_value("spacelen")).get_as_int();
00334                 int subtract_width = 0;
00335                 if (options->exists("subtract_width"))
00336                         subtract_width = CL_String(
00337                                 options->get_value("subtract_width")).get_as_int();
00338 
00339                 int num_tcols = 1;
00340                 int *tcols = NULL;
00341                 if (num_tcols > 0)
00342                 {
00343                         tcols = new int[num_tcols];
00344                         tcols[0] = 0;
00345                 }
00346 
00347                 CL_SurfaceProvider* provider = 0;
00348 
00349                 for (std::list<CL_ResourceSource_Surface*>::iterator it = CL_Res_Surface::surface_sources.begin();
00350                      it != CL_Res_Surface::surface_sources.end();
00351                      it++)
00352                 {
00353                         if ((*it)->can_create (ext, options))
00354                         {
00355                                 provider = (*it)->create (location, options, parent);
00356                                 break;
00357                         }
00358                 }
00359                 cl_assert (provider != NULL);
00360 
00361                 font_desc = new CL_Font_Description(provider,
00362                                                     x, y,
00363                                                     tcols, num_tcols,
00364                                                     space_len,
00365                                                     subtract_width,
00366                                                     options->get_value("letters").c_str());
00367         }
00368 }

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