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 #include "CEGUIXMLParser.h"
00035 #include <iostream>
00036 #include <cmath>
00037
00038
00039 namespace CEGUI
00040 {
00041
00042
00043
00044
00045
00046 const char Imageset::ImagesetSchemaName[] = "Imageset.xsd";
00047
00048
00049
00050
00051
00052 Imageset::Imageset(const String& name, Texture* texture) :
00053 d_name(name),
00054 d_texture(texture)
00055 {
00056 if (d_texture == NULL)
00057 {
00058 throw NullObjectException((utf8*)"Imageset::Imageset - Texture object supplied for Imageset creation must not be NULL");
00059 }
00060
00061
00062 d_autoScale = false;
00063 setNativeResolution(Size(DefaultNativeHorzRes, DefaultNativeVertRes));
00064 }
00065
00066
00067
00068
00069
00070 Imageset::Imageset(const String& filename, const String& resourceGroup)
00071 {
00072
00073 d_autoScale = false;
00074 setNativeResolution(Size(DefaultNativeHorzRes, DefaultNativeVertRes));
00075
00076 d_texture = NULL;
00077 load(filename, resourceGroup);
00078 }
00079
00080
00081 Imageset::Imageset(const String& name, const String& filename, const String& resourceGroup) :
00082 d_name(name)
00083 {
00084
00085 d_texture =
00086 System::getSingleton().getRenderer()->createTexture(filename, resourceGroup);
00087
00088
00089 d_autoScale = true;
00090 setNativeResolution(
00091 Size(d_texture->getWidth(), d_texture->getHeight()));
00092
00093
00094 defineImage(
00095 "full_image",
00096 Rect(0, 0, d_texture->getWidth(), d_texture->getHeight()),
00097 Point(0, 0)
00098 );
00099 }
00100
00101
00102
00103
00104
00105 Imageset::~Imageset(void)
00106 {
00107 unload();
00108 }
00109
00110
00111
00112
00113
00114 void Imageset::setTexture(Texture* texture)
00115 {
00116 if (d_texture == NULL)
00117 {
00118 throw NullObjectException((utf8*)"Imageset::setTexture - Texture object supplied for Imageset creation must not be NULL");
00119 }
00120
00121 d_texture = texture;
00122 }
00123
00124
00125
00126
00127
00128 void Imageset::load(const String& filename, const String& resourceGroup)
00129 {
00130
00131 unload();
00132
00133 if (filename.empty() || (filename == (utf8*)""))
00134 {
00135 throw InvalidRequestException((utf8*)"Imageset::load - Filename supplied for Imageset loading must be valid");
00136 }
00137
00138
00139 Imageset_xmlHandler handler(this);
00140
00141
00142 try
00143 {
00144 System::getSingleton().getXMLParser()->parseXMLFile(handler, filename, ImagesetSchemaName, resourceGroup);
00145 }
00146 catch(...)
00147 {
00148 unload();
00149
00150 Logger::getSingleton().logEvent("Imageset::load - loading of Imageset from file '" + filename +"' failed.", Errors);
00151 throw;
00152 }
00153
00154 }
00155
00156
00157
00158
00159
00160 const Image& Imageset::getImage(const String& name) const
00161 {
00162 ImageRegistry::const_iterator pos = d_images.find(name);
00163
00164 if (pos == d_images.end())
00165 {
00166 throw UnknownObjectException("Imageset::getImage - The Image named '" + name + "' could not be found in Imageset '" + d_name + "'.");
00167 }
00168
00169 return pos->second;
00170 }
00171
00172
00173
00174
00175
00176 void Imageset::defineImage(const String& name, const Rect& image_rect, const Point& render_offset)
00177 {
00178 if (isImageDefined(name))
00179 {
00180 throw AlreadyExistsException("Imageset::defineImage - An image with the name '" + name + "' already exists in Imageset '" + d_name + "'.");
00181 }
00182
00183
00184 float hscale = d_autoScale ? d_horzScaling : 1.0f;
00185 float vscale = d_autoScale ? d_vertScaling : 1.0f;
00186
00187
00188 d_images[name] = Image(this, name, image_rect, render_offset, hscale, vscale);
00189
00190 CEGUI_LOGINSANE("Image '" + name + "' has been defined for Imageset '" + d_name + "'.")
00191 }
00192
00193
00194
00195
00196
00197
00198 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
00199 {
00200
00201 Rect final_rect(dest_rect.getIntersection(clip_rect));
00202
00203
00204 if (final_rect.getWidth() != 0)
00205 {
00206 float x_scale = 1.0f / (float)d_texture->getWidth();
00207 float y_scale = 1.0f / (float)d_texture->getHeight();
00208
00209 float tex_per_pix_x = source_rect.getWidth() / dest_rect.getWidth();
00210 float tex_per_pix_y = source_rect.getHeight() / dest_rect.getHeight();
00211
00212
00213 Rect tex_rect((source_rect.d_left + ((final_rect.d_left - dest_rect.d_left) * tex_per_pix_x)) * x_scale,
00214 (source_rect.d_top + ((final_rect.d_top - dest_rect.d_top) * tex_per_pix_y)) * y_scale,
00215 (source_rect.d_right + ((final_rect.d_right - dest_rect.d_right) * tex_per_pix_x)) * x_scale,
00216 (source_rect.d_bottom + ((final_rect.d_bottom - dest_rect.d_bottom) * tex_per_pix_y)) * y_scale);
00217
00218 final_rect.d_left = PixelAligned(final_rect.d_left);
00219 final_rect.d_right = PixelAligned(final_rect.d_right);
00220 final_rect.d_top = PixelAligned(final_rect.d_top);
00221 final_rect.d_bottom = PixelAligned(final_rect.d_bottom);
00222
00223
00224 d_texture->getRenderer()->addQuad(final_rect, z, d_texture, tex_rect, colours, quad_split_mode);
00225 }
00226
00227 }
00228
00229
00230
00231
00232 void Imageset::unload(void)
00233 {
00234 undefineAllImages();
00235
00236
00237 System::getSingleton().getRenderer()->destroyTexture(d_texture);
00238 d_texture = NULL;
00239 }
00240
00241
00242
00243
00244
00245 void Imageset::updateImageScalingFactors(void)
00246 {
00247 float hscale, vscale;
00248
00249 if (d_autoScale)
00250 {
00251 hscale = d_horzScaling;
00252 vscale = d_vertScaling;
00253 }
00254 else
00255 {
00256 hscale = vscale = 1.0f;
00257 }
00258
00259 ImageRegistry::iterator pos = d_images.begin(), end = d_images.end();
00260 for(; pos != end; ++pos)
00261 {
00262 pos->second.setHorzScaling(hscale);
00263 pos->second.setVertScaling(vscale);
00264 }
00265
00266 }
00267
00268
00269
00270
00271
00272 void Imageset::setAutoScalingEnabled(bool setting)
00273 {
00274 if (setting != d_autoScale)
00275 {
00276 d_autoScale = setting;
00277 updateImageScalingFactors();
00278 }
00279
00280 }
00281
00282
00283
00284
00285
00286 void Imageset::setNativeResolution(const Size& size)
00287 {
00288 d_nativeHorzRes = size.d_width;
00289 d_nativeVertRes = size.d_height;
00290
00291
00292 notifyScreenResolution(System::getSingleton().getRenderer()->getSize());
00293 }
00294
00295
00296
00297
00298
00299 void Imageset::notifyScreenResolution(const Size& size)
00300 {
00301 d_horzScaling = size.d_width / d_nativeHorzRes;
00302 d_vertScaling = size.d_height / d_nativeVertRes;
00303
00304 if (d_autoScale)
00305 {
00306 updateImageScalingFactors();
00307 }
00308
00309 }
00310
00311 void Imageset::writeXMLToStream(OutStream& out_stream) const
00312 {
00313
00314 out_stream << "<Imageset Name=\"" << d_name << "\" ";
00315 out_stream << "Filename=\"" << d_textureFilename << "\" ";
00316
00317 if (d_nativeHorzRes != DefaultNativeHorzRes)
00318 out_stream << "NativeHorzRes=\"" << static_cast<uint>(d_nativeHorzRes) << "\" ";
00319
00320 if (d_nativeVertRes != DefaultNativeVertRes)
00321 out_stream << "NativeVertRes=\"" << static_cast<uint>(d_nativeVertRes) << "\" ";
00322
00323 if (d_autoScale)
00324 out_stream << "AutoScaled=\"True\" ";
00325
00326 out_stream << ">" << std::endl;
00327
00328
00329 ImageIterator image = getIterator();
00330
00331 while (!image.isAtEnd())
00332 {
00333 image.getCurrentValue().writeXMLToStream(out_stream);
00334 ++image;
00335 }
00336
00337
00338 out_stream << "</Imageset>" << std::endl;
00339 }
00340
00341
00342
00343
00344
00345
00346 Imageset::ImageIterator Imageset::getIterator(void) const
00347 {
00348 return ImageIterator(d_images.begin(), d_images.end());
00349 }
00350
00351
00352 void Imageset::undefineImage(const String& name)
00353 {
00354 d_images.erase(name);
00355
00356 CEGUI_LOGINSANE("Image '" + name + "' has been removed from Imageset '" + d_name + "'.")
00357 }
00358
00359
00360 void Imageset::undefineAllImages(void)
00361 {
00362 d_images.clear();
00363
00364 CEGUI_LOGINSANE("All images have been removed from Imageset '" + d_name + "'.")
00365 }
00366
00367 }