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

CEGUIImageset.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIImageset.cpp
00003         created:        21/2/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implements the Imageset class
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00025 *************************************************************************/
00026 #include "CEGUIImageset.h"
00027 #include "CEGUIExceptions.h"
00028 #include "CEGUITexture.h"
00029 #include "CEGUIRenderer.h"
00030 #include "CEGUISystem.h"
00031 #include "CEGUIImageset_xmlHandler.h"
00032 #include "CEGUILogger.h"
00033 #include "CEGUIDataContainer.h"
00034 
00035 #include "xercesc/sax2/SAX2XMLReader.hpp"
00036 #include "xercesc/sax2/XMLReaderFactory.hpp"
00037 #include "xercesc/framework/MemBufInputSource.hpp"
00038 
00039 #include <iostream>
00040 #include <cmath>
00041 
00042 // Start of CEGUI namespace section
00043 namespace CEGUI
00044 {
00045 
00046 /*************************************************************************
00047         Definition of constant data for Imageset (and sub-classes)
00048 *************************************************************************/
00049 // Declared in Imageset
00050 const char      Imageset::ImagesetSchemaName[]                  = "Imageset.xsd";
00051 
00052 
00053 /*************************************************************************
00054         constructor
00055 *************************************************************************/
00056 Imageset::Imageset(const String& name, Texture* texture) :
00057         d_name(name),
00058         d_texture(texture)
00059 {
00060         if (d_texture == NULL)
00061         {
00062                 throw NullObjectException((utf8*)"Imageset::Imageset - Texture object supplied for Imageset creation must not be NULL");
00063         }
00064 
00065         // defaults for scaling options
00066         d_autoScale = false;
00067         setNativeResolution(Size(DefaultNativeHorzRes, d_nativeVertRes));
00068 }
00069 
00070 
00071 /*************************************************************************
00072         construct and initialise Imageset from the specified file.
00073 *************************************************************************/
00074 Imageset::Imageset(const String& filename, const String& resourceGroup)
00075 {
00076         // defaults for scaling options
00077         d_autoScale = false;
00078         setNativeResolution(Size(DefaultNativeHorzRes, d_nativeVertRes));
00079 
00080         d_texture = NULL;
00081         load(filename, resourceGroup);
00082 }
00083 
00084 
00085 /*************************************************************************
00086         destructor
00087 *************************************************************************/
00088 Imageset::~Imageset(void)
00089 {
00090         unload();
00091 }
00092 
00093 
00094 /*************************************************************************
00095         Set texture for use by this imageset object
00096 *************************************************************************/
00097 void Imageset::setTexture(Texture* texture)
00098 {
00099         if (d_texture == NULL)
00100         {
00101                 throw NullObjectException((utf8*)"Imageset::setTexture - Texture object supplied for Imageset creation must not be NULL");
00102         }
00103 
00104         d_texture = texture;
00105 }
00106 
00107 
00108 /*************************************************************************
00109         load Imageset data from the specified file
00110 *************************************************************************/
00111 void Imageset::load(const String& filename, const String& resourceGroup)
00112 {
00113         XERCES_CPP_NAMESPACE_USE
00114 
00115         // unload old data and texture.
00116         unload();
00117 
00118         if (filename.empty() || (filename == (utf8*)""))
00119         {
00120                 throw InvalidRequestException((utf8*)"Imageset::load - Filename supplied for Imageset loading must be valid");
00121         }
00122 
00123         SAX2XMLReader* parser = XMLReaderFactory::createXMLReader();
00124 
00125         // set basic settings we want from parser
00126         parser->setFeature(XMLUni::fgSAX2CoreValidation, true);
00127         parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
00128         parser->setFeature(XMLUni::fgXercesSchema, true);
00129         parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);
00130 
00131 //    InputSourceContainer imagesetSchemaData;
00132 //    System::getSingleton().getResourceProvider()->loadInputSourceContainer(ImagesetSchemaName, imagesetSchemaData);
00133 //    parser->loadGrammar(*(imagesetSchemaData.getDataPtr()), Grammar::SchemaGrammarType, true);
00134 
00135     RawDataContainer rawSchemaData;
00136     System::getSingleton().getResourceProvider()->loadRawDataContainer(ImagesetSchemaName, rawSchemaData, resourceGroup);
00137     MemBufInputSource  imagesetSchemaData(rawSchemaData.getDataPtr(), rawSchemaData.getSize(), ImagesetSchemaName, false);
00138     parser->loadGrammar(imagesetSchemaData, Grammar::SchemaGrammarType, true);
00139     // enable grammar reuse
00140     parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
00141 
00142         // setup schema for Imageset data
00143         XMLCh* pval = XMLString::transcode(ImagesetSchemaName);
00144         parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval);
00145         XMLString::release(&pval);
00146 
00147         // setup handler object
00148         Imageset_xmlHandler handler(this);
00149         parser->setContentHandler(&handler);
00150         parser->setErrorHandler(&handler);
00151 
00152 //    InputSourceContainer imagesetData;
00153 //    System::getSingleton().getResourceProvider()->loadInputSourceContainer(filename,imagesetData);
00154 
00155     RawDataContainer rawXMLData;
00156     System::getSingleton().getResourceProvider()->loadRawDataContainer(filename, rawXMLData, resourceGroup);
00157     MemBufInputSource  imagesetData(rawXMLData.getDataPtr(), rawXMLData.getSize(), filename.c_str(), false);
00158 
00159         // do parse (which uses handler to create actual data)
00160         try
00161         {
00162 //        parser->parse(*(imagesetData.getDataPtr()));
00163         parser->parse(imagesetData);
00164         }
00165         catch(const XMLException& exc)
00166         {
00167                 if (exc.getCode() != XMLExcepts::NoError)
00168                 {
00169                         unload();
00170                         delete parser;
00171 
00172                         char* excmsg = XMLString::transcode(exc.getMessage());
00173                         String message((utf8*)"Imageset::load - An error occurred while parsing Imageset file '" + filename + "'.  Additional information: ");
00174                         message += (utf8*)excmsg;
00175                         XMLString::release(&excmsg);
00176 
00177                         throw FileIOException(message);
00178                 }
00179 
00180         }
00181         catch(const SAXParseException& exc)
00182         {
00183                 unload();
00184                 delete parser;
00185 
00186                 char* excmsg = XMLString::transcode(exc.getMessage());
00187                 String message((utf8*)"Imageset::load - An error occurred while parsing Imageset file '" + filename + "'.  Additional information: ");
00188                 message += (utf8*)excmsg;
00189                 XMLString::release(&excmsg);
00190 
00191                 throw FileIOException(message);
00192         }
00193         catch(...)
00194         {
00195                 unload();
00196                 delete parser;
00197 
00198                 throw FileIOException((utf8*)"Imageset::load - An unexpected error occurred while parsing Imageset file '" + filename + "'.");
00199         }
00200 
00201         // cleanup
00202         delete parser;
00203 }
00204 
00205  
00206 /*************************************************************************
00207         return the Image object for the named image
00208 *************************************************************************/
00209 const Image& Imageset::getImage(const String& name) const
00210 {
00211         ImageRegistry::const_iterator   pos = d_images.find(name);
00212 
00213         if (pos == d_images.end())
00214         {
00215                 throw   UnknownObjectException("Imageset::getImage - The Image named '" + name + "' could not be found in Imageset '" + d_name + "'.");
00216         }
00217 
00218         return pos->second;
00219 }
00220 
00221 
00222 /*************************************************************************
00223         defines a new Image.
00224 *************************************************************************/
00225 void Imageset::defineImage(const String& name, const Rect& image_rect, const Point& render_offset)
00226 {
00227         if (isImageDefined(name))
00228         {
00229                 throw AlreadyExistsException("Imageset::defineImage - An image with the name '" + name + "' already exists in Imageset '" + d_name + "'.");
00230         }
00231 
00232         // get scaling factors
00233         float hscale = d_autoScale ? d_horzScaling : 1.0f;
00234         float vscale = d_autoScale ? d_vertScaling : 1.0f;
00235 
00236         // add the Image definition
00237         d_images[name] = Image(this, name, image_rect, render_offset, hscale, vscale);
00238 
00239         CEGUI_LOGINSANE("Image '" + name + "' has been defined for Imageset '" + d_name + "'.")
00240 }
00241 
00242 
00243 /*************************************************************************
00244         Queues an area of the associated Texture the be drawn on the screen.
00245         Low-level routine not normally used!
00246 *************************************************************************/
00247 void Imageset::draw(const Rect& source_rect, const Rect& dest_rect, float z, const Rect& clip_rect,const ColourRect& colours, QuadSplitMode quad_split_mode) const
00248 {
00249         // get the rect area that we will actually draw to (i.e. perform clipping)
00250         Rect final_rect(dest_rect.getIntersection(clip_rect));
00251 
00252         // check if rect was totally clipped
00253         if (final_rect.getWidth() != 0)
00254         {
00255                 float x_scale = 1.0f / (float)d_texture->getWidth();
00256                 float y_scale = 1.0f / (float)d_texture->getHeight();
00257 
00258                 float tex_per_pix_x = source_rect.getWidth() / dest_rect.getWidth();
00259                 float tex_per_pix_y = source_rect.getHeight() / dest_rect.getHeight();
00260 
00261                 // calculate final, clipped, texture co-ordinates
00262                 Rect  tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale,
00263                         (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale,
00264                         (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale,
00265                         (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale);
00266 
00267                 final_rect.d_left       = PixelAligned(final_rect.d_left);
00268                 final_rect.d_right      = PixelAligned(final_rect.d_right);
00269                 final_rect.d_top        = PixelAligned(final_rect.d_top);
00270                 final_rect.d_bottom     = PixelAligned(final_rect.d_bottom);
00271 
00272                 // queue a quad to be rendered
00273                 d_texture->getRenderer()->addQuad(final_rect, z, d_texture, tex_rect, colours, quad_split_mode);
00274         }
00275 
00276 }
00277 
00278 /*************************************************************************
00279         Unload all data, leaving Imageset in a clean (but unusable) state
00280 *************************************************************************/
00281 void Imageset::unload(void)
00282 {
00283         undefineAllImages();
00284 
00285         // cleanup texture
00286         System::getSingleton().getRenderer()->destroyTexture(d_texture);
00287         d_texture = NULL;
00288 }
00289 
00290 
00291 /*************************************************************************
00292         Sets the scaling factor for all Images that are a part of this Imageset.
00293 *************************************************************************/
00294 void Imageset::updateImageScalingFactors(void)
00295 {
00296         float hscale, vscale;
00297 
00298         if (d_autoScale)
00299         {
00300                 hscale = d_horzScaling;
00301                 vscale = d_vertScaling;
00302         }
00303         else
00304         {
00305                 hscale = vscale = 1.0f;
00306         }
00307 
00308         ImageRegistry::iterator pos = d_images.begin(), end = d_images.end();
00309         for(; pos != end; ++pos)
00310         {
00311                 pos->second.setHorzScaling(hscale);
00312                 pos->second.setVertScaling(vscale);
00313         }
00314 
00315 }
00316 
00317 
00318 /*************************************************************************
00319         Enable or disable auto-scaling for this Imageset.
00320 *************************************************************************/
00321 void Imageset::setAutoScalingEnabled(bool setting)
00322 {
00323         if (setting != d_autoScale)
00324         {
00325                 d_autoScale = setting;
00326                 updateImageScalingFactors();
00327         }
00328 
00329 }
00330 
00331 
00332 /*************************************************************************
00333         Set the native resolution for this Imageset
00334 *************************************************************************/
00335 void Imageset::setNativeResolution(const Size& size)
00336 {
00337         d_nativeHorzRes = size.d_width;
00338         d_nativeVertRes = size.d_height;
00339 
00340         // re-calculate scaling factors & notify images as required
00341         notifyScreenResolution(System::getSingleton().getRenderer()->getSize());
00342 }
00343 
00344 
00345 /*************************************************************************
00346         Notify the Imageset of the current (usually new) display resolution.
00347 *************************************************************************/
00348 void Imageset::notifyScreenResolution(const Size& size)
00349 {
00350         d_horzScaling = size.d_width / d_nativeHorzRes;
00351         d_vertScaling = size.d_height / d_nativeVertRes;
00352 
00353         if (d_autoScale)
00354         {
00355                 updateImageScalingFactors();
00356         }
00357 
00358 }
00359 
00360 
00361 /*************************************************************************
00362         Return an iterator object that can be used to iterate over the Image
00363         objects in the Imageset.
00364 *************************************************************************/
00365 Imageset::ImageIterator Imageset::getIterator(void) const
00366 {
00367         return ImageIterator(d_images.begin(), d_images.end());
00368 }
00369 
00370 
00371 void Imageset::undefineImage(const String& name)
00372 {
00373         d_images.erase(name);
00374 
00375         CEGUI_LOGINSANE("Image '" + name + "' has been removed from Imageset '" + d_name + "'.")
00376 }
00377 
00378 
00379 void Imageset::undefineAllImages(void)
00380 {
00381         d_images.clear();
00382 
00383         CEGUI_LOGINSANE("All images have been removed from Imageset '" + d_name + "'.")
00384 }
00385 
00386 } // End of  CEGUI namespace section

Generated on Wed Feb 16 12:41:06 2005 for Crazy Eddies GUI System by  doxygen 1.3.9.1