00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
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
00043 namespace CEGUI
00044 {
00045
00046
00047
00048
00049
00050 const char Imageset::ImagesetSchemaName[] = "Imageset.xsd";
00051
00052
00053
00054
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
00066 d_autoScale = false;
00067 setNativeResolution(Size(DefaultNativeHorzRes, d_nativeVertRes));
00068 }
00069
00070
00071
00072
00073
00074 Imageset::Imageset(const String& filename, const String& resourceGroup)
00075 {
00076
00077 d_autoScale = false;
00078 setNativeResolution(Size(DefaultNativeHorzRes, d_nativeVertRes));
00079
00080 d_texture = NULL;
00081 load(filename, resourceGroup);
00082 }
00083
00084
00085
00086
00087
00088 Imageset::~Imageset(void)
00089 {
00090 unload();
00091 }
00092
00093
00094
00095
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
00110
00111 void Imageset::load(const String& filename, const String& resourceGroup)
00112 {
00113 XERCES_CPP_NAMESPACE_USE
00114
00115
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
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
00132
00133
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
00140 parser->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
00141
00142
00143 XMLCh* pval = XMLString::transcode(ImagesetSchemaName);
00144 parser->setProperty(XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation, pval);
00145 XMLString::release(&pval);
00146
00147
00148 Imageset_xmlHandler handler(this);
00149 parser->setContentHandler(&handler);
00150 parser->setErrorHandler(&handler);
00151
00152
00153
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
00160 try
00161 {
00162
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
00202 delete parser;
00203 }
00204
00205
00206
00207
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
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
00233 float hscale = d_autoScale ? d_horzScaling : 1.0f;
00234 float vscale = d_autoScale ? d_vertScaling : 1.0f;
00235
00236
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
00245
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
00250 Rect final_rect(dest_rect.getIntersection(clip_rect));
00251
00252
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
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
00273 d_texture->getRenderer()->addQuad(final_rect, z, d_texture, tex_rect, colours, quad_split_mode);
00274 }
00275
00276 }
00277
00278
00279
00280
00281 void Imageset::unload(void)
00282 {
00283 undefineAllImages();
00284
00285
00286 System::getSingleton().getRenderer()->destroyTexture(d_texture);
00287 d_texture = NULL;
00288 }
00289
00290
00291
00292
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
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
00334
00335 void Imageset::setNativeResolution(const Size& size)
00336 {
00337 d_nativeHorzRes = size.d_width;
00338 d_nativeVertRes = size.d_height;
00339
00340
00341 notifyScreenResolution(System::getSingleton().getRenderer()->getSize());
00342 }
00343
00344
00345
00346
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
00363
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 }