Implement duplicate sprite with flatten layers (it was removed

temporally with the introduction of Document class).
This commit is contained in:
David Capello 2011-03-27 23:21:22 -03:00
parent 341e298a6e
commit 9077ab8357
7 changed files with 78 additions and 147 deletions

View File

@ -323,129 +323,65 @@ Document* Document::duplicate(DuplicateType type) const
sourceSprite->getWidth(),
sourceSprite->getHeight(), sourceSprite->getPalette(0)->size()));
// TODO IMPLEMENT THIS
UniquePtr<Document> documentCopy(new Document(spriteCopy));
spriteCopy.release();
return documentCopy;
}
spriteCopy->setTotalFrames(sourceSprite->getTotalFrames());
spriteCopy->setCurrentFrame(sourceSprite->getCurrentFrame());
#if 0
Sprite* Sprite::createFlattenCopy(const Sprite& src_sprite)
{
Sprite* dst_sprite = new Sprite();
SpriteImpl* dst_sprite_impl = SpriteImpl::copyBase(dst_sprite, src_sprite.m_impl);
dst_sprite->m_impl = dst_sprite_impl;
// Flatten layers
ASSERT(src_sprite.getFolder() != NULL);
Layer* flat_layer;
try {
flat_layer = layer_new_flatten_copy(dst_sprite,
src_sprite.getFolder(),
0, 0, src_sprite.getWidth(), src_sprite.getHeight(),
0, src_sprite.getTotalFrames()-1);
}
catch (const std::bad_alloc&) {
delete dst_sprite;
throw;
}
// Add and select the new flat layer
dst_sprite->getFolder()->add_layer(flat_layer);
dst_sprite->setCurrentLayer(flat_layer);
return dst_sprite;
}
/**
* Makes a copy "sprite" without the layers (only with the empty layer set)
*/
SpriteImpl* SpriteImpl::copyBase(Sprite* new_sprite, const SpriteImpl* src_sprite)
{
SpriteImpl* dst_sprite = new SpriteImpl(new_sprite,
src_sprite->m_imgtype,
src_sprite->m_width, src_sprite->m_height,
src_sprite->getPalette(0)->size());
// Delete the original empty stock from the dst_sprite
delete dst_sprite->m_stock;
// Clone the src_sprite stock
dst_sprite->m_stock = new Stock(*src_sprite->m_stock);
// Copy general properties
dst_sprite->m_filename = src_sprite->m_filename;
dst_sprite->setTotalFrames(src_sprite->m_frames);
std::copy(src_sprite->m_frlens.begin(),
src_sprite->m_frlens.end(),
dst_sprite->m_frlens.begin());
// Copy frames duration
for (int i = 0; i < sourceSprite->getTotalFrames(); ++i)
spriteCopy->setFrameDuration(i, sourceSprite->getFrameDuration(i));
// Copy color palettes
{
PalettesList::const_iterator end = src_sprite->m_palettes.end();
PalettesList::const_iterator it = src_sprite->m_palettes.begin();
PalettesList::const_iterator it = sourceSprite->getPalettes().begin();
PalettesList::const_iterator end = sourceSprite->getPalettes().end();
for (; it != end; ++it) {
Palette* pal = *it;
dst_sprite->setPalette(pal, true);
const Palette* pal = *it;
spriteCopy->setPalette(pal, true);
}
}
// Copy path
if (dst_sprite->m_path) {
delete dst_sprite->m_path;
dst_sprite->m_path = NULL;
switch (type) {
case DuplicateExactCopy:
{
// TODO IMPLEMENT THIS
}
break;
case DuplicateWithFlattenLayers:
{
// Flatten layers
ASSERT(sourceSprite->getFolder() != NULL);
LayerImage* flatLayer = layer_new_flatten_copy
(spriteCopy,
sourceSprite->getFolder(),
0, 0, sourceSprite->getWidth(), sourceSprite->getHeight(),
0, sourceSprite->getTotalFrames()-1);
// Add and select the new flat layer
spriteCopy->getFolder()->add_layer(flatLayer);
spriteCopy->setCurrentLayer(flatLayer);
// Configure the layer as background only if the original
// sprite has a background layer.
if (sourceSprite->getBackgroundLayer() == NULL)
flatLayer->configureAsBackground();
}
break;
}
if (src_sprite->m_path)
dst_sprite->m_path = new Path(*src_sprite->m_path);
UniquePtr<Document> documentCopy(new Document(spriteCopy));
spriteCopy.release();
// Copy mask
if (dst_sprite->m_mask) {
delete dst_sprite->m_mask;
dst_sprite->m_mask = NULL;
}
documentCopy->setMask(getMask());
documentCopy->m_maskVisible = m_maskVisible;
documentCopy->m_preferred = m_preferred;
documentCopy->generateMaskBoundaries();
if (src_sprite->m_mask)
dst_sprite->m_mask = mask_new_copy(src_sprite->m_mask);
return dst_sprite;
return documentCopy.release();
}
SpriteImpl* SpriteImpl::copyLayers(SpriteImpl* dst_sprite, const SpriteImpl* src_sprite)
{
// Copy layers
if (dst_sprite->m_folder) {
delete dst_sprite->m_folder; // delete
dst_sprite->m_folder = NULL;
}
ASSERT(src_sprite->getFolder() != NULL);
// Disable undo temporarily
dst_sprite->getUndo()->setEnabled(false);
dst_sprite->m_folder = src_sprite->getFolder()->duplicate_for(dst_sprite->m_self);
dst_sprite->getUndo()->setEnabled(true);
if (dst_sprite->m_folder == NULL) {
delete dst_sprite;
return NULL;
}
// Selected layer
if (src_sprite->getCurrentLayer() != NULL) {
int selected_layer = src_sprite->layerToIndex(src_sprite->getCurrentLayer());
dst_sprite->setCurrentLayer(dst_sprite->indexToLayer(selected_layer));
}
dst_sprite->generateMaskBoundaries();
return dst_sprite;
}
#endif
//////////////////////////////////////////////////////////////////////
// Multi-threading ("sprite wrappers" use this)

View File

@ -147,6 +147,7 @@ public:
// Copying
void copyLayerContent(const LayerImage* sourceLayer, LayerImage* destLayer) const;
Document* duplicate(DuplicateType type) const;
//////////////////////////////////////////////////////////////////////

View File

@ -20,6 +20,7 @@
#include "raster/layer.h"
#include "base/unique_ptr.h"
#include "raster/blend.h"
#include "raster/cel.h"
#include "raster/image.h"
@ -314,42 +315,35 @@ void LayerFolder::move_layer(Layer* layer, Layer* after)
* @param dst_sprite The sprite where to put the new flattened layer.
* @param src_layer Generally a set of layers to be flattened.
*/
Layer* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer,
int x, int y, int w, int h, int frmin, int frmax)
LayerImage* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer,
int x, int y, int w, int h, int frmin, int frmax)
{
LayerImage* flat_layer = new LayerImage(dst_sprite);
UniquePtr<LayerImage> flatLayer(new LayerImage(dst_sprite));
try {
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_new(flat_layer->getSprite()->getImgType(), w, h);
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_new(flatLayer->getSprite()->getImgType(), w, h);
try {
/* create the new cel for the output layer (add the image to
stock too) */
Cel* cel = cel_new(frame, flat_layer->getSprite()->getStock()->addImage(image));
cel_set_position(cel, x, y);
try {
// Create the new cel for the output layer (add the image to stock too).
Cel* cel = cel_new(frame, flatLayer->getSprite()->getStock()->addImage(image));
cel_set_position(cel, x, y);
/* clear the image and render this frame */
image_clear(image, 0);
layer_render(src_layer, image, -x, -y, frame);
flat_layer->addCel(cel);
}
catch (...) {
delete image;
throw;
}
// 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;
}
}
}
catch (...) {
delete flat_layer;
throw;
}
return flat_layer;
return flatLayer.release();
}
void layer_render(const Layer* layer, Image* image, int x, int y, int frame)

View File

@ -131,7 +131,7 @@ public:
int getMemSize() const;
LayerList get_layers_list() { return m_layers; }
const LayerList& get_layers_list() { return m_layers; }
LayerIterator get_layer_begin() { return m_layers.begin(); }
LayerIterator get_layer_end() { return m_layers.end(); }
LayerConstIterator get_layer_begin() const { return m_layers.begin(); }
@ -150,8 +150,8 @@ private:
LayerList m_layers;
};
Layer* layer_new_flatten_copy(Sprite* dst_sprite, const Layer* src_layer,
int x, int y, int w, int h, int frmin, int frmax);
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);

View File

@ -219,12 +219,12 @@ Palette* Sprite::getPalette(int frame) const
return found;
}
PalettesList Sprite::getPalettes() const
const PalettesList& Sprite::getPalettes() const
{
return m_palettes;
}
void Sprite::setPalette(Palette* pal, bool truncate)
void Sprite::setPalette(const Palette* pal, bool truncate)
{
ASSERT(pal != NULL);

View File

@ -85,9 +85,9 @@ public:
// Palettes
Palette* getPalette(int frame) const;
PalettesList getPalettes() const;
const PalettesList& getPalettes() const;
void setPalette(Palette* pal, bool truncate);
void setPalette(const Palette* pal, bool truncate);
// Removes all palettes from the sprites except the first one.
void resetPalettes();

View File

@ -597,7 +597,7 @@ void UndoTransaction::flattenLayers(int bgcolor)
m_sprite->setCurrentLayer(background);
}
/* remove old layers */
// Remove old layers.
LayerList layers = m_sprite->getFolder()->get_layers_list();
LayerIterator it = layers.begin();
LayerIterator end = layers.end();
@ -606,13 +606,13 @@ void UndoTransaction::flattenLayers(int bgcolor)
if (*it != background) {
Layer* old_layer = *it;
// remove the layer
// Remove the layer
if (isEnabled())
m_undoHistory->undo_remove_layer(old_layer);
m_sprite->getFolder()->remove_layer(old_layer);
// destroy the layer
// Destroy the layer
delete old_layer;
}
}