diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ee02d7e96..65d7442ee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -144,6 +144,7 @@ add_library(aseprite-library documents.cpp drop_files.cpp file_system.cpp + flatten.cpp gfxmode.cpp gui_xml.cpp ini_file.cpp diff --git a/src/document.cpp b/src/document.cpp index c5cbc0860..d33036aa9 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -25,6 +25,7 @@ #include "base/scoped_lock.h" #include "base/unique_ptr.h" #include "file/format_options.h" +#include "flatten.h" #include "objects_container_impl.h" #include "raster/cel.h" #include "raster/layer.h" @@ -446,10 +447,10 @@ Document* Document::duplicate(DuplicateType type) const // Flatten layers ASSERT(sourceSprite->getFolder() != NULL); - LayerImage* flatLayer = layer_new_flatten_copy + LayerImage* flatLayer = create_flatten_layer_copy (spriteCopy, sourceSprite->getFolder(), - 0, 0, sourceSprite->getWidth(), sourceSprite->getHeight(), + gfx::Rect(0, 0, sourceSprite->getWidth(), sourceSprite->getHeight()), 0, sourceSprite->getTotalFrames()-1); // Add and select the new flat layer diff --git a/src/flatten.cpp b/src/flatten.cpp new file mode 100644 index 000000000..fbabfa487 --- /dev/null +++ b/src/flatten.cpp @@ -0,0 +1,89 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "config.h" + +#include "base/unique_ptr.h" +#include "gfx/rect.h" +#include "raster/cel.h" +#include "raster/image.h" +#include "raster/layer.h" +#include "raster/sprite.h" +#include "raster/stock.h" + +static bool has_cels(const Layer* layer, int frame); + +LayerImage* create_flatten_layer_copy(Sprite* dstSprite, const Layer* srcLayer, + const gfx::Rect& bounds, int frmin, int frmax) +{ + UniquePtr flatLayer(new LayerImage(dstSprite)); + + for (int frame=frmin; frame<=frmax; frame++) { + // Does this frame have cels to render? + if (has_cels(srcLayer, frame)) { + // Create a new image to render each frame. + UniquePtr imageWrap(Image::create(flatLayer->getSprite()->getPixelFormat(), bounds.w, bounds.h)); + + // Add the image into the sprite's stock too. + int imageIndex = flatLayer->getSprite()->getStock()->addImage(imageWrap); + Image* image = imageWrap.release(); + + // Create the new cel for the output layer. + UniquePtr cel(new Cel(frame, imageIndex)); + cel->setPosition(bounds.x, bounds.y); + + // Clear the image and render this frame. + image->clear(0); + layer_render(srcLayer, image, -bounds.x, -bounds.y, frame); + + // Add the cel (and release the UniquePtr). + flatLayer->addCel(cel); + cel.release(); + } + } + + return flatLayer.release(); +} + +// Returns true if the "layer" or its children have any cel to render +// in the given "frame". +static bool has_cels(const Layer* layer, int frame) +{ + if (!layer->is_readable()) + return false; + + switch (layer->getType()) { + + case GFXOBJ_LAYER_IMAGE: + return static_cast(layer)->getCel(frame) ? true: false; + + case GFXOBJ_LAYER_FOLDER: { + LayerConstIterator it = static_cast(layer)->get_layer_begin(); + LayerConstIterator end = static_cast(layer)->get_layer_end(); + + for (; it != end; ++it) { + if (has_cels(*it, frame)) + return true; + } + break; + } + + } + + return false; +} diff --git a/src/flatten.h b/src/flatten.h new file mode 100644 index 000000000..992999983 --- /dev/null +++ b/src/flatten.h @@ -0,0 +1,38 @@ +/* ASEPRITE + * Copyright (C) 2001-2012 David Capello + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef FLATTEN_H_INCLUDED +#define FLATTEN_H_INCLUDED + +#include "gfx/Rect.h" + +class Sprite; +class Layer; +class LayerImage; + +// Returns a new layer with the given layer at "srcLayer" rendered +// frame by frame from "frmin" to "frmax" (inclusive). The routine +// flattens all children of "srcLayer" to an unique output layer. +// +// Note: The layer is not added to the given sprite, but is related to +// it, so you'll be able to add the flatten layer only into the given +// sprite. +LayerImage* create_flatten_layer_copy(Sprite* dstSprite, const Layer* srcLayer, + const gfx::Rect& bounds, int frmin, int frmax); + +#endif diff --git a/src/raster/layer.cpp b/src/raster/layer.cpp index 6562058da..8644bbe23 100644 --- a/src/raster/layer.cpp +++ b/src/raster/layer.cpp @@ -20,7 +20,6 @@ #include "raster/layer.h" -#include "base/unique_ptr.h" #include "raster/blend.h" #include "raster/cel.h" #include "raster/image.h" @@ -30,8 +29,6 @@ #include #include -static bool has_cels(const Layer* layer, int frame); - ////////////////////////////////////////////////////////////////////// // Layer class @@ -304,48 +301,6 @@ void LayerFolder::move_layer(Layer* layer, Layer* after) // jlist_prepend(m_layers, layer); } -////////////////////////////////////////////////////////////////////// - -/** - * Returns a new layer (flat_layer) with all "layer" rendered frame by - * frame from "frmin" to "frmax" (inclusive). "layer" can be a set of - * layers, so the routine flattens all children to an unique output - * layer. - * - * @param dst_sprite The sprite where to put the new flattened layer. - * @param src_layer Generally a set of layers to be flattened. - */ -LayerImage* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer, - int x, int y, int w, int h, int frmin, int frmax) -{ - UniquePtr flatLayer(new LayerImage(dst_sprite)); - - for (int frame=frmin; frame<=frmax; frame++) { - // Does this frame have cels to render? - if (has_cels(src_layer, frame)) { - // Create a new image - Image* image = Image::create(flatLayer->getSprite()->getPixelFormat(), w, h); - - try { - // Create the new cel for the output layer (add the image to stock too). - Cel* cel = new Cel(frame, flatLayer->getSprite()->getStock()->addImage(image)); - cel->setPosition(x, y); - - // Clear the image and render this frame. - image_clear(image, 0); - layer_render(src_layer, image, -x, -y, frame); - flatLayer->addCel(cel); - } - catch (...) { - delete image; - throw; - } - } - } - - return flatLayer.release(); -} - void layer_render(const Layer* layer, Image* image, int x, int y, int frame) { if (!layer->is_readable()) @@ -387,33 +342,3 @@ void layer_render(const Layer* layer, Image* image, int x, int y, int frame) } } - -/** - * Returns true if the "layer" (or him childs) has cels to render in - * frame. - */ -static bool has_cels(const Layer* layer, int frame) -{ - if (!layer->is_readable()) - return false; - - switch (layer->getType()) { - - case GFXOBJ_LAYER_IMAGE: - return static_cast(layer)->getCel(frame) ? true: false; - - case GFXOBJ_LAYER_FOLDER: { - LayerConstIterator it = static_cast(layer)->get_layer_begin(); - LayerConstIterator end = static_cast(layer)->get_layer_end(); - - for (; it != end; ++it) { - if (has_cels(*it, frame)) - return true; - } - break; - } - - } - - return false; -} diff --git a/src/raster/layer.h b/src/raster/layer.h index 9d51deee1..b7b5d4b3f 100644 --- a/src/raster/layer.h +++ b/src/raster/layer.h @@ -150,9 +150,6 @@ private: LayerList m_layers; }; -LayerImage* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer, - int x, int y, int w, int h, int frmin, int frmax); - void layer_render(const Layer* layer, Image *image, int x, int y, int frame); #endif