| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | // Aseprite Document Library
 | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  | // Copyright (c) 2001-2015 David Capello
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | //
 | 
					
						
							|  |  |  | // This file is released under the terms of the MIT license.
 | 
					
						
							|  |  |  | // Read LICENSE.txt for more information.
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #ifdef HAVE_CONFIG_H
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | #include "config.h"
 | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | #include "doc/sprite.h"
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-24 06:19:18 +08:00
										 |  |  | #include "base/memory.h"
 | 
					
						
							| 
									
										
										
										
											2010-10-01 08:38:01 +08:00
										 |  |  | #include "base/remove_from_container.h"
 | 
					
						
							| 
									
										
										
										
											2013-03-31 06:53:52 +08:00
										 |  |  | #include "base/unique_ptr.h"
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  | #include "doc/cels_range.h"
 | 
					
						
							| 
									
										
										
										
											2014-12-28 22:06:11 +08:00
										 |  |  | #include "doc/doc.h"
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | #include "doc/image_bits.h"
 | 
					
						
							|  |  |  | #include "doc/primitives.h"
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 11:06:43 +08:00
										 |  |  | #include <cstring>
 | 
					
						
							|  |  |  | #include <vector>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | namespace doc { | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  | static Layer* index2layer(const Layer* layer, const LayerIndex& index, int* index_count); | 
					
						
							|  |  |  | static LayerIndex layer2index(const Layer* layer, const Layer* find_layer, int* index_count); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-01 09:27:51 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | // Constructors/Destructor
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  | Sprite::Sprite(PixelFormat format, int width, int height, int ncolors) | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  |   : Object(ObjectType::Sprite) | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  |   , m_document(NULL) | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  |   , m_format(format) | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   , m_width(width) | 
					
						
							|  |  |  |   , m_height(height) | 
					
						
							| 
									
										
										
										
											2012-07-09 08:09:09 +08:00
										 |  |  |   , m_frames(1) | 
					
						
							| 
									
										
										
										
											2008-10-01 09:27:51 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-04 10:33:44 +08:00
										 |  |  |   ASSERT(width > 0 && height > 0); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |   m_frlens.push_back(100);      // First frame with 100 msecs of duration
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   m_folder = new LayerFolder(this); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |   // Generate palette
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |   Palette pal(frame_t(0), ncolors); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  |   switch (format) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |     // For colored images
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     case IMAGE_RGB: | 
					
						
							|  |  |  |     case IMAGE_INDEXED: | 
					
						
							| 
									
										
										
										
											2010-05-30 21:48:37 +08:00
										 |  |  |       pal.resize(ncolors); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |     // For black and white images
 | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |     case IMAGE_GRAYSCALE: | 
					
						
							|  |  |  |     case IMAGE_BITMAP: | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |       for (int c=0; c<ncolors; c++) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         int g = 255 * c / (ncolors-1); | 
					
						
							|  |  |  |         g = MID(0, g, 255); | 
					
						
							| 
									
										
										
										
											2013-11-10 06:59:05 +08:00
										 |  |  |         pal.setEntry(c, rgba(g, g, g, 255)); | 
					
						
							| 
									
										
										
										
											2010-03-28 23:15:32 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-04-21 10:44:31 +08:00
										 |  |  |   // Initial RGB map
 | 
					
						
							|  |  |  |   m_rgbMap = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-21 04:17:35 +08:00
										 |  |  |   // The transparent color for indexed images is 0 by default
 | 
					
						
							|  |  |  |   m_transparentColor = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   setPalette(&pal, true); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | Sprite::~Sprite() | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   // Destroy layers
 | 
					
						
							|  |  |  |   delete m_folder; | 
					
						
							| 
									
										
										
										
											2008-10-01 09:27:51 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   // Destroy palettes
 | 
					
						
							| 
									
										
										
										
											2010-10-01 08:38:01 +08:00
										 |  |  |   { | 
					
						
							|  |  |  |     PalettesList::iterator end = m_palettes.end(); | 
					
						
							|  |  |  |     PalettesList::iterator it = m_palettes.begin(); | 
					
						
							|  |  |  |     for (; it != end; ++it) | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |       delete *it;               // palette
 | 
					
						
							| 
									
										
										
										
											2008-10-01 09:27:51 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-23 11:06:43 +08:00
										 |  |  |   // Destroy RGB map
 | 
					
						
							| 
									
										
										
										
											2010-04-21 10:44:31 +08:00
										 |  |  |   delete m_rgbMap; | 
					
						
							| 
									
										
										
										
											2008-10-01 09:27:51 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  | // static
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | Sprite* Sprite::createBasicSprite(doc::PixelFormat format, int width, int height, int ncolors) | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   // Create the sprite.
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  |   base::UniquePtr<doc::Sprite> sprite(new doc::Sprite(format, width, height, ncolors)); | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |   sprite->setTotalFrames(doc::frame_t(1)); | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create the main image.
 | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |   doc::ImageRef image(doc::Image::create(format, width, height)); | 
					
						
							|  |  |  |   doc::clear_image(image, 0); | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Create the first transparent layer.
 | 
					
						
							|  |  |  |   { | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  |     base::UniquePtr<doc::LayerImage> layer(new doc::LayerImage(sprite)); | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  |     layer->setName("Layer 1"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Create the cel.
 | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |       base::UniquePtr<doc::Cel> cel(new doc::Cel(doc::frame_t(0), image)); | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  |       cel->setPosition(0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // Add the cel in the layer.
 | 
					
						
							|  |  |  |       layer->addCel(cel); | 
					
						
							|  |  |  |       cel.release();            // Release the cel because it is in the layer
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Add the layer in the sprite.
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |     sprite->folder()->addLayer(layer.release()); // Release the layer because it's owned by the sprite
 | 
					
						
							| 
									
										
										
										
											2014-07-29 11:53:24 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return sprite.release(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Main properties
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  | void Sprite::setPixelFormat(PixelFormat format) | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  |   m_format = format; | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void Sprite::setSize(int width, int height) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   ASSERT(width > 0); | 
					
						
							|  |  |  |   ASSERT(height > 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_width = width; | 
					
						
							|  |  |  |   m_height = height; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Sprite::needAlpha() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  |   switch (m_format) { | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |     case IMAGE_RGB: | 
					
						
							|  |  |  |     case IMAGE_GRAYSCALE: | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |       return (backgroundLayer() == NULL); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2014-08-10 05:04:53 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | bool Sprite::supportAlpha() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   switch (m_format) { | 
					
						
							|  |  |  |     case IMAGE_RGB: | 
					
						
							|  |  |  |     case IMAGE_GRAYSCALE: | 
					
						
							|  |  |  |       return true; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-08 11:30:36 +08:00
										 |  |  | void Sprite::setTransparentColor(color_t color) | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   m_transparentColor = color; | 
					
						
							| 
									
										
										
										
											2014-06-03 11:05:57 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-10 09:36:42 +08:00
										 |  |  |   // Change the mask color of all images.
 | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |   std::vector<Image*> images; | 
					
						
							|  |  |  |   getImages(images); | 
					
						
							|  |  |  |   for (Image* image : images) | 
					
						
							|  |  |  |     image->setMaskColor(color); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int Sprite::getMemSize() const | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-06-03 11:05:57 +08:00
										 |  |  |   int size = 0; | 
					
						
							| 
									
										
										
										
											2008-03-23 02:43:56 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |   std::vector<Image*> images; | 
					
						
							|  |  |  |   getImages(images); | 
					
						
							|  |  |  |   for (Image* image : images) | 
					
						
							|  |  |  |     size += image->getRowStrideSize() * image->height(); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   return size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Layers
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  | LayerFolder* Sprite::folder() const | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   return m_folder; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  | LayerImage* Sprite::backgroundLayer() const | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |   if (folder()->getLayersCount() > 0) { | 
					
						
							|  |  |  |     Layer* bglayer = *folder()->getLayerBegin(); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 23:43:25 +08:00
										 |  |  |     if (bglayer->isBackground()) { | 
					
						
							|  |  |  |       ASSERT(bglayer->isImage()); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       return static_cast<LayerImage*>(bglayer); | 
					
						
							| 
									
										
										
										
											2010-12-12 23:10:46 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   } | 
					
						
							|  |  |  |   return NULL; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  | LayerIndex Sprite::countLayers() const | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |   return LayerIndex(folder()->getLayersCount()); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-04 19:19:02 +08:00
										 |  |  | LayerIndex Sprite::firstLayer() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return LayerIndex(0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | LayerIndex Sprite::lastLayer() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return LayerIndex(folder()->getLayersCount()-1); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-28 22:06:11 +08:00
										 |  |  | Layer* Sprite::layer(int layerIndex) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return indexToLayer(LayerIndex(layerIndex)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  | Layer* Sprite::indexToLayer(LayerIndex index) const | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-08-08 07:19:31 +08:00
										 |  |  |   if (index < LayerIndex(0)) | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   int index_count = -1; | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |   return index2layer(folder(), index, &index_count); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  | LayerIndex Sprite::layerToIndex(const Layer* layer) const | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   int index_count = -1; | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |   return layer2index(folder(), layer, &index_count); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-08 07:19:31 +08:00
										 |  |  | void Sprite::getLayersList(std::vector<Layer*>& layers) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   // TODO support subfolders
 | 
					
						
							|  |  |  |   LayerConstIterator it = m_folder->getLayerBegin(); | 
					
						
							|  |  |  |   LayerConstIterator end = m_folder->getLayerEnd(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (; it != end; ++it) { | 
					
						
							|  |  |  |     layers.push_back(*it); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Palettes
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-28 22:06:11 +08:00
										 |  |  | Palette* Sprite::palette(frame_t frame) const | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-04 10:33:44 +08:00
										 |  |  |   ASSERT(frame >= 0); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   Palette* found = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 08:38:01 +08:00
										 |  |  |   PalettesList::const_iterator end = m_palettes.end(); | 
					
						
							|  |  |  |   PalettesList::const_iterator it = m_palettes.begin(); | 
					
						
							|  |  |  |   for (; it != end; ++it) { | 
					
						
							|  |  |  |     Palette* pal = *it; | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |     if (frame < pal->frame()) | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       break; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     found = pal; | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |     if (frame == pal->frame()) | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       break; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-04 10:33:44 +08:00
										 |  |  |   ASSERT(found != NULL); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   return found; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-28 10:21:22 +08:00
										 |  |  | const PalettesList& Sprite::getPalettes() const | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   return m_palettes; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-28 10:21:22 +08:00
										 |  |  | void Sprite::setPalette(const Palette* pal, bool truncate) | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-04 10:33:44 +08:00
										 |  |  |   ASSERT(pal != NULL); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (!truncate) { | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |     Palette* sprite_pal = palette(pal->frame()); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     pal->copyColorsTo(sprite_pal); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   else { | 
					
						
							|  |  |  |     Palette* other; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 08:38:01 +08:00
										 |  |  |     PalettesList::iterator end = m_palettes.end(); | 
					
						
							|  |  |  |     PalettesList::iterator it = m_palettes.begin(); | 
					
						
							|  |  |  |     for (; it != end; ++it) { | 
					
						
							|  |  |  |       other = *it; | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |       if (pal->frame() == other->frame()) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         pal->copyColorsTo(other); | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |       else if (pal->frame() < other->frame()) | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         break; | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 08:38:01 +08:00
										 |  |  |     m_palettes.insert(it, new Palette(*pal)); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | void Sprite::resetPalettes() | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-10-01 08:38:01 +08:00
										 |  |  |   PalettesList::iterator end = m_palettes.end(); | 
					
						
							|  |  |  |   PalettesList::iterator it = m_palettes.begin(); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-03 09:58:50 +08:00
										 |  |  |   if (it != end) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |     ++it;                       // Leave the first palette only.
 | 
					
						
							| 
									
										
										
										
											2010-10-03 09:58:50 +08:00
										 |  |  |     while (it != end) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |       delete *it;               // palette
 | 
					
						
							| 
									
										
										
										
											2010-10-03 09:58:50 +08:00
										 |  |  |       it = m_palettes.erase(it); | 
					
						
							| 
									
										
										
										
											2011-01-19 06:22:03 +08:00
										 |  |  |       end = m_palettes.end(); | 
					
						
							| 
									
										
										
										
											2010-10-03 09:58:50 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | void Sprite::deletePalette(Palette* pal) | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-08-04 10:33:44 +08:00
										 |  |  |   ASSERT(pal != NULL); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-10-01 08:38:01 +08:00
										 |  |  |   base::remove_from_container(m_palettes, pal); | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |   delete pal;                   // palette
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | RgbMap* Sprite::rgbMap(frame_t frame) | 
					
						
							| 
									
										
										
										
											2010-04-21 10:44:31 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |   int mask_color = (backgroundLayer() ? -1: transparentColor()); | 
					
						
							| 
									
										
										
										
											2014-07-20 09:01:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   if (m_rgbMap == NULL) { | 
					
						
							|  |  |  |     m_rgbMap = new RgbMap(); | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |     m_rgbMap->regenerate(palette(frame), mask_color); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |   else if (!m_rgbMap->match(palette(frame))) { | 
					
						
							|  |  |  |     m_rgbMap->regenerate(palette(frame), mask_color); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-20 09:01:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   return m_rgbMap; | 
					
						
							| 
									
										
										
										
											2010-04-21 10:44:31 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Frames
 | 
					
						
							| 
									
										
										
										
											2008-10-14 11:11:59 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | void Sprite::addFrame(frame_t newFrame) | 
					
						
							| 
									
										
										
										
											2013-03-12 07:29:45 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |   setTotalFrames(m_frames+1); | 
					
						
							|  |  |  |   for (frame_t i=m_frames-1; i>=newFrame; --i) | 
					
						
							|  |  |  |     setFrameDuration(i, frameDuration(i-1)); | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |   folder()->displaceFrames(newFrame, +1); | 
					
						
							| 
									
										
										
										
											2013-03-12 07:29:45 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  | void Sprite::removeFrame(frame_t frame) | 
					
						
							| 
									
										
										
										
											2013-03-12 07:29:45 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  |   folder()->displaceFrames(frame, -1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |   frame_t newTotal = m_frames-1; | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  |   for (frame_t i=frame; i<newTotal; ++i) | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |     setFrameDuration(i, frameDuration(i+1)); | 
					
						
							| 
									
										
										
										
											2013-03-12 07:29:45 +08:00
										 |  |  |   setTotalFrames(newTotal); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | void Sprite::setTotalFrames(frame_t frames) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |   frames = MAX(frame_t(1), frames); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   m_frlens.resize(frames); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (frames > m_frames) { | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  |     for (frame_t c=m_frames; c<frames; ++c) | 
					
						
							|  |  |  |       m_frlens[c] = m_frlens[m_frames-1]; | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   m_frames = frames; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | int Sprite::frameDuration(frame_t frame) const | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   if (frame >= 0 && frame < m_frames) | 
					
						
							|  |  |  |     return m_frlens[frame]; | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | void Sprite::setFrameDuration(frame_t frame, int msecs) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   if (frame >= 0 && frame < m_frames) | 
					
						
							|  |  |  |     m_frlens[frame] = MID(1, msecs, 65535); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | void Sprite::setFrameRangeDuration(frame_t from, frame_t to, int msecs) | 
					
						
							| 
									
										
										
										
											2013-12-23 03:30:04 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   std::fill( | 
					
						
							|  |  |  |     m_frlens.begin()+(size_t)from, | 
					
						
							|  |  |  |     m_frlens.begin()+(size_t)to+1, MID(1, msecs, 65535)); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | void Sprite::setDurationForAllFrames(int msecs) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   std::fill(m_frlens.begin(), m_frlens.end(), MID(1, msecs, 65535)); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  | // Shared Images and CelData (for linked Cels)
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  | ImageRef Sprite::getImageRef(ObjectId imageId) | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  |   for (Cel* cel : cels()) { | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |     if (cel->image()->id() == imageId) | 
					
						
							|  |  |  |       return cel->imageRef(); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  |   return ImageRef(nullptr); | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  | CelDataRef Sprite::getCelDataRef(ObjectId celDataId) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  |   for (Cel* cel : cels()) { | 
					
						
							|  |  |  |     if (cel->dataRef()->id() == celDataId) | 
					
						
							|  |  |  |       return cel->dataRef(); | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  |   return CelDataRef(nullptr); | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Images
 | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  | void Sprite::replaceImage(ObjectId curImageId, const ImageRef& newImage) | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  |   for (Cel* cel : cels()) { | 
					
						
							|  |  |  |     if (cel->image()->id() == curImageId) | 
					
						
							|  |  |  |       cel->data()->setImage(newImage); | 
					
						
							| 
									
										
										
										
											2015-01-19 09:05:33 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-04 21:58:14 +08:00
										 |  |  | // TODO replace it with a images iterator
 | 
					
						
							|  |  |  | void Sprite::getImages(std::vector<Image*>& images) const | 
					
						
							| 
									
										
										
										
											2014-05-02 22:28:03 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  |   for (const auto& cel : uniqueCels()) | 
					
						
							|  |  |  |     images.push_back(cel->image()); | 
					
						
							| 
									
										
										
										
											2014-05-02 22:28:03 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | void Sprite::remapImages(frame_t frameFrom, frame_t frameTo, const std::vector<uint8_t>& mapping) | 
					
						
							| 
									
										
										
										
											2010-06-17 13:13:42 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2012-02-13 10:21:06 +08:00
										 |  |  |   ASSERT(m_format == IMAGE_INDEXED); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |   ASSERT(mapping.size() == 256); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  |   for (Cel* cel : cels()) { | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |     // Remap this Cel because is inside the specified range
 | 
					
						
							| 
									
										
										
										
											2014-07-30 12:28:15 +08:00
										 |  |  |     if (cel->frame() >= frameFrom && | 
					
						
							|  |  |  |         cel->frame() <= frameTo) { | 
					
						
							|  |  |  |       Image* image = cel->image(); | 
					
						
							| 
									
										
										
										
											2013-11-10 06:59:05 +08:00
										 |  |  |       LockImageBits<IndexedTraits> bits(image); | 
					
						
							|  |  |  |       LockImageBits<IndexedTraits>::iterator | 
					
						
							|  |  |  |         it = bits.begin(), | 
					
						
							|  |  |  |         end = bits.end(); | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-10 06:59:05 +08:00
										 |  |  |       for (; it != end; ++it) | 
					
						
							|  |  |  |         *it = mapping[*it]; | 
					
						
							| 
									
										
										
										
											2011-03-25 00:06:40 +08:00
										 |  |  |     } | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2010-06-17 13:13:42 +08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // Drawing
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 07:39:11 +08:00
										 |  |  | void Sprite::pickCels(int x, int y, frame_t frame, int opacityThreshold, CelList& cels) const | 
					
						
							| 
									
										
										
										
											2014-11-17 05:33:31 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   std::vector<Layer*> layers; | 
					
						
							|  |  |  |   getLayersList(layers); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   for (int i=(int)layers.size()-1; i>=0; --i) { | 
					
						
							|  |  |  |     Layer* layer = layers[i]; | 
					
						
							| 
									
										
										
										
											2014-12-03 22:15:09 +08:00
										 |  |  |     if (!layer->isImage() || !layer->isVisible()) | 
					
						
							| 
									
										
										
										
											2014-11-17 05:33:31 +08:00
										 |  |  |       continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-29 08:04:08 +08:00
										 |  |  |     Cel* cel = layer->cel(frame); | 
					
						
							| 
									
										
										
										
											2014-11-17 05:33:31 +08:00
										 |  |  |     if (!cel) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Image* image = cel->image(); | 
					
						
							|  |  |  |     if (!image) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!cel->bounds().contains(gfx::Point(x, y))) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     color_t color = get_pixel(image, | 
					
						
							|  |  |  |       x - cel->x(), | 
					
						
							|  |  |  |       y - cel->y()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     bool isOpaque = true; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (image->pixelFormat()) { | 
					
						
							|  |  |  |       case IMAGE_RGB: | 
					
						
							|  |  |  |         isOpaque = (rgba_geta(color) >= opacityThreshold); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case IMAGE_INDEXED: | 
					
						
							|  |  |  |         isOpaque = (color != image->maskColor()); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |       case IMAGE_GRAYSCALE: | 
					
						
							|  |  |  |         isOpaque = (graya_geta(color) >= opacityThreshold); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (!isOpaque) | 
					
						
							|  |  |  |       continue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cels.push_back(cel); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   fflush(stdout); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-02-09 22:40:43 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							|  |  |  | // CelsRange
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CelsRange Sprite::cels() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return CelsRange(this, frame_t(0), lastFrame()); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CelsRange Sprite::cels(frame_t frame) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return CelsRange(this, frame, frame); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | CelsRange Sprite::uniqueCels() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   return CelsRange(this, frame_t(0), lastFrame(), CelsRange::UNIQUE); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-03-31 08:43:18 +08:00
										 |  |  | //////////////////////////////////////////////////////////////////////
 | 
					
						
							| 
									
										
										
										
											2008-03-27 22:29:33 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  | static Layer* index2layer(const Layer* layer, const LayerIndex& index, int* index_count) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |   if (index == *index_count) | 
					
						
							| 
									
										
										
										
											2009-06-11 08:59:57 +08:00
										 |  |  |     return (Layer*)layer; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     (*index_count)++; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 23:43:25 +08:00
										 |  |  |     if (layer->isFolder()) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       Layer *found; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 23:43:25 +08:00
										 |  |  |       LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin(); | 
					
						
							|  |  |  |       LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd(); | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       for (; it != end; ++it) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         if ((found = index2layer(*it, index, index_count))) | 
					
						
							|  |  |  |           return found; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return NULL; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  | static LayerIndex layer2index(const Layer* layer, const Layer* find_layer, int* index_count) | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | { | 
					
						
							|  |  |  |   if (layer == find_layer) | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  |     return LayerIndex(*index_count); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   else { | 
					
						
							| 
									
										
										
										
											2008-02-04 10:37:26 +08:00
										 |  |  |     (*index_count)++; | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 23:43:25 +08:00
										 |  |  |     if (layer->isFolder()) { | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       int found; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-01-11 23:43:25 +08:00
										 |  |  |       LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin(); | 
					
						
							|  |  |  |       LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd(); | 
					
						
							| 
									
										
										
										
											2009-11-17 21:12:26 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |       for (; it != end; ++it) { | 
					
						
							| 
									
										
										
										
											2012-01-06 06:45:03 +08:00
										 |  |  |         if ((found = layer2index(*it, find_layer, index_count)) >= 0) | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  |           return LayerIndex(found); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-08-24 08:32:55 +08:00
										 |  |  |     return LayerIndex(-1); | 
					
						
							| 
									
										
										
										
											2007-09-19 07:57:02 +08:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-08-06 08:20:19 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-10-21 09:21:31 +08:00
										 |  |  | } // namespace doc
 |