2013-08-08 21:01:20 -03:00
|
|
|
/* Aseprite
|
2013-01-27 12:13:13 -03:00
|
|
|
* Copyright (C) 2001-2013 David Capello
|
2007-09-18 23:57:02 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2013-08-05 21:20:19 -03:00
|
|
|
#ifdef HAVE_CONFIG_H
|
2007-09-18 23:57:02 +00:00
|
|
|
#include "config.h"
|
2013-08-05 21:20:19 -03:00
|
|
|
#endif
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2011-03-24 13:10:48 -03:00
|
|
|
#include "raster/layer.h"
|
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
#include "raster/blend.h"
|
2007-11-16 20:49:40 +00:00
|
|
|
#include "raster/cel.h"
|
2007-09-18 23:57:02 +00:00
|
|
|
#include "raster/image.h"
|
2013-11-09 19:59:05 -03:00
|
|
|
#include "raster/primitives.h"
|
2007-12-05 01:30:50 +00:00
|
|
|
#include "raster/sprite.h"
|
2007-09-18 23:57:02 +00:00
|
|
|
#include "raster/stock.h"
|
2011-03-24 11:50:00 -03:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <string.h>
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2013-08-05 21:20:19 -03:00
|
|
|
namespace raster {
|
2008-10-01 01:27:51 +00:00
|
|
|
|
2013-11-09 19:59:05 -03:00
|
|
|
Layer::Layer(ObjectType type, Sprite* sprite)
|
|
|
|
: Object(type)
|
2008-10-01 01:27:51 +00:00
|
|
|
{
|
2013-11-09 19:59:05 -03:00
|
|
|
ASSERT(type == OBJECT_LAYER_IMAGE || type == OBJECT_LAYER_FOLDER);
|
2008-10-01 01:27:51 +00:00
|
|
|
|
2010-09-19 00:03:32 -03:00
|
|
|
setName("Layer");
|
2008-10-01 01:27:51 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
m_sprite = sprite;
|
|
|
|
m_parent = NULL;
|
|
|
|
m_flags =
|
2008-10-01 01:27:51 +00:00
|
|
|
LAYER_IS_READABLE |
|
|
|
|
LAYER_IS_WRITABLE;
|
|
|
|
}
|
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
Layer::~Layer()
|
|
|
|
{
|
|
|
|
}
|
2008-10-01 01:27:51 +00:00
|
|
|
|
2010-10-03 15:51:03 -03:00
|
|
|
int Layer::getMemSize() const
|
|
|
|
{
|
|
|
|
return sizeof(Layer);
|
|
|
|
}
|
|
|
|
|
2013-01-11 12:43:25 -03:00
|
|
|
Layer* Layer::getPrevious() const
|
2009-11-17 13:12:26 +00:00
|
|
|
{
|
|
|
|
if (m_parent != NULL) {
|
|
|
|
LayerConstIterator it =
|
2013-01-11 12:43:25 -03:00
|
|
|
std::find(m_parent->getLayerBegin(),
|
|
|
|
m_parent->getLayerEnd(), this);
|
2009-11-17 13:12:26 +00:00
|
|
|
|
2013-01-11 12:43:25 -03:00
|
|
|
if (it != m_parent->getLayerEnd() &&
|
|
|
|
it != m_parent->getLayerBegin()) {
|
2009-11-17 13:12:26 +00:00
|
|
|
it--;
|
|
|
|
return *it;
|
2008-10-01 01:27:51 +00:00
|
|
|
}
|
2009-11-17 13:12:26 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2008-10-01 01:27:51 +00:00
|
|
|
|
2013-01-11 12:43:25 -03:00
|
|
|
Layer* Layer::getNext() const
|
2009-11-17 13:12:26 +00:00
|
|
|
{
|
|
|
|
if (m_parent != NULL) {
|
|
|
|
LayerConstIterator it =
|
2013-01-11 12:43:25 -03:00
|
|
|
std::find(m_parent->getLayerBegin(),
|
|
|
|
m_parent->getLayerEnd(), this);
|
2009-11-17 13:12:26 +00:00
|
|
|
|
2013-01-11 12:43:25 -03:00
|
|
|
if (it != m_parent->getLayerEnd()) {
|
2009-11-17 13:12:26 +00:00
|
|
|
it++;
|
2013-01-11 12:43:25 -03:00
|
|
|
if (it != m_parent->getLayerEnd())
|
2012-01-05 19:45:03 -03:00
|
|
|
return *it;
|
2008-10-01 01:27:51 +00:00
|
|
|
}
|
|
|
|
}
|
2009-11-17 13:12:26 +00:00
|
|
|
return NULL;
|
2008-10-01 01:27:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////
|
2009-11-17 13:12:26 +00:00
|
|
|
// LayerImage class
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
LayerImage::LayerImage(Sprite* sprite)
|
2013-11-09 19:59:05 -03:00
|
|
|
: Layer(OBJECT_LAYER_IMAGE, sprite)
|
2009-11-17 13:12:26 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
LayerImage::~LayerImage()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2011-03-24 13:15:09 -03:00
|
|
|
destroyAllCels();
|
2009-11-17 13:12:26 +00:00
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-10-03 15:51:03 -03:00
|
|
|
int LayerImage::getMemSize() const
|
|
|
|
{
|
|
|
|
int size = sizeof(LayerImage);
|
|
|
|
CelConstIterator it = getCelBegin();
|
|
|
|
CelConstIterator end = getCelEnd();
|
|
|
|
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
const Cel* cel = *it;
|
|
|
|
size += cel->getMemSize();
|
|
|
|
|
2011-03-28 00:24:27 -03:00
|
|
|
const Image* image = getSprite()->getStock()->getImage(cel->getImage());
|
2010-10-03 15:51:03 -03:00
|
|
|
size += image->getMemSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2011-03-24 13:15:09 -03:00
|
|
|
void LayerImage::destroyAllCels()
|
2009-11-17 13:12:26 +00:00
|
|
|
{
|
2010-09-19 00:15:44 -03:00
|
|
|
CelIterator it = getCelBegin();
|
|
|
|
CelIterator end = getCelEnd();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
for (; it != end; ++it) {
|
|
|
|
Cel* cel = *it;
|
2011-03-28 00:24:27 -03:00
|
|
|
Image* image = getSprite()->getStock()->getImage(cel->getImage());
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2010-08-03 23:33:44 -03:00
|
|
|
ASSERT(image != NULL);
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2010-09-30 22:38:26 -03:00
|
|
|
getSprite()->getStock()->removeImage(image);
|
2013-03-30 19:53:52 -03:00
|
|
|
delete image;
|
2011-03-28 00:24:27 -03:00
|
|
|
delete cel;
|
2009-11-17 13:12:26 +00:00
|
|
|
}
|
2010-03-26 11:44:27 -03:00
|
|
|
m_cels.clear();
|
2009-11-17 13:12:26 +00:00
|
|
|
}
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2014-05-02 11:28:03 -03:00
|
|
|
void LayerImage::getCels(CelList& cels) const
|
2009-11-17 13:12:26 +00:00
|
|
|
{
|
2014-05-02 11:28:03 -03:00
|
|
|
CelConstIterator it = getCelBegin();
|
|
|
|
CelConstIterator end = getCelEnd();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
for (; it != end; ++it)
|
|
|
|
cels.push_back(*it);
|
|
|
|
}
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2010-09-19 00:26:33 -03:00
|
|
|
void LayerImage::addCel(Cel *cel)
|
2009-11-17 13:12:26 +00:00
|
|
|
{
|
2010-09-19 00:15:44 -03:00
|
|
|
CelIterator it = getCelBegin();
|
|
|
|
CelIterator end = getCelEnd();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
for (; it != end; ++it) {
|
2011-03-28 00:24:27 -03:00
|
|
|
if ((*it)->getFrame() > cel->getFrame())
|
2009-11-17 13:12:26 +00:00
|
|
|
break;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
m_cels.insert(it, cel);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2008-03-22 18:43:56 +00:00
|
|
|
/**
|
2009-11-17 13:12:26 +00:00
|
|
|
* Removes the cel from the layer.
|
2008-03-22 18:43:56 +00:00
|
|
|
*
|
2009-11-17 13:12:26 +00:00
|
|
|
* It doesn't destroy the cel, you have to delete it after calling
|
|
|
|
* this routine.
|
2008-03-22 18:43:56 +00:00
|
|
|
*/
|
2010-09-19 00:26:33 -03:00
|
|
|
void LayerImage::removeCel(Cel *cel)
|
2008-03-22 18:43:56 +00:00
|
|
|
{
|
2009-11-17 13:12:26 +00:00
|
|
|
CelIterator it = std::find(m_cels.begin(), m_cels.end(), cel);
|
2008-03-22 18:43:56 +00:00
|
|
|
|
2010-08-03 23:33:44 -03:00
|
|
|
ASSERT(it != m_cels.end());
|
2008-03-22 18:43:56 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
m_cels.erase(it);
|
2008-03-22 18:43:56 +00:00
|
|
|
}
|
|
|
|
|
2014-04-09 21:56:06 -03:00
|
|
|
void LayerImage::moveCel(Cel* cel, FrameNumber frame)
|
|
|
|
{
|
|
|
|
removeCel(cel);
|
|
|
|
cel->setFrame(frame);
|
|
|
|
addCel(cel);
|
|
|
|
}
|
|
|
|
|
2012-07-08 21:09:09 -03:00
|
|
|
const Cel* LayerImage::getCel(FrameNumber frame) const
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-09-19 00:15:44 -03:00
|
|
|
CelConstIterator it = getCelBegin();
|
|
|
|
CelConstIterator end = getCelEnd();
|
2008-03-27 14:29:33 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
for (; it != end; ++it) {
|
|
|
|
const Cel* cel = *it;
|
2011-03-28 00:24:27 -03:00
|
|
|
if (cel->getFrame() == frame)
|
2009-11-17 13:12:26 +00:00
|
|
|
return cel;
|
|
|
|
}
|
2008-03-27 14:29:33 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-03-27 14:29:33 +00:00
|
|
|
|
2012-07-08 21:09:09 -03:00
|
|
|
Cel* LayerImage::getCel(FrameNumber frame)
|
2009-11-17 13:12:26 +00:00
|
|
|
{
|
2011-03-26 18:49:29 -03:00
|
|
|
return const_cast<Cel*>(static_cast<const LayerImage*>(this)->getCel(frame));
|
2008-03-27 14:29:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Configures some properties of the specified layer to make it as the
|
|
|
|
* "Background" of the sprite.
|
|
|
|
*
|
|
|
|
* You can't use this routine if the sprite already has a background
|
|
|
|
* layer.
|
|
|
|
*/
|
2010-09-19 00:17:21 -03:00
|
|
|
void LayerImage::configureAsBackground()
|
2008-03-27 14:29:33 +00:00
|
|
|
{
|
2010-08-03 23:33:44 -03:00
|
|
|
ASSERT(getSprite() != NULL);
|
|
|
|
ASSERT(getSprite()->getBackgroundLayer() == NULL);
|
2008-03-27 14:29:33 +00:00
|
|
|
|
2013-01-11 12:43:25 -03:00
|
|
|
setMoveable(false);
|
|
|
|
setBackground(true);
|
2010-09-19 00:03:32 -03:00
|
|
|
setName("Background");
|
2008-03-27 14:29:33 +00:00
|
|
|
|
2012-08-18 22:21:42 -03:00
|
|
|
getSprite()->getFolder()->stackLayer(this, NULL);
|
2008-03-27 14:29:33 +00:00
|
|
|
}
|
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
//////////////////////////////////////////////////////////////////////
|
|
|
|
// LayerFolder class
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
LayerFolder::LayerFolder(Sprite* sprite)
|
2013-11-09 19:59:05 -03:00
|
|
|
: Layer(OBJECT_LAYER_FOLDER, sprite)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2010-09-19 00:03:32 -03:00
|
|
|
setName("Layer Set");
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
LayerFolder::~LayerFolder()
|
2008-03-27 14:29:33 +00:00
|
|
|
{
|
2010-09-19 00:15:44 -03:00
|
|
|
destroyAllLayers();
|
2008-01-23 16:16:43 +00:00
|
|
|
}
|
|
|
|
|
2010-09-19 00:15:44 -03:00
|
|
|
void LayerFolder::destroyAllLayers()
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2013-01-11 12:43:25 -03:00
|
|
|
LayerIterator it = getLayerBegin();
|
|
|
|
LayerIterator end = getLayerEnd();
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
for (; it != end; ++it) {
|
|
|
|
Layer* layer = *it;
|
|
|
|
delete layer;
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
2010-03-26 11:44:27 -03:00
|
|
|
m_layers.clear();
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2010-10-03 15:51:03 -03:00
|
|
|
int LayerFolder::getMemSize() const
|
|
|
|
{
|
|
|
|
int size = sizeof(LayerFolder);
|
2013-01-11 12:43:25 -03:00
|
|
|
LayerConstIterator it = getLayerBegin();
|
|
|
|
LayerConstIterator end = getLayerEnd();
|
2010-10-03 15:51:03 -03:00
|
|
|
|
|
|
|
for (; it != end; ++it) {
|
|
|
|
const Layer* layer = *it;
|
|
|
|
size += layer->getMemSize();
|
|
|
|
}
|
|
|
|
|
|
|
|
return size;
|
|
|
|
}
|
|
|
|
|
2014-05-02 11:28:03 -03:00
|
|
|
void LayerFolder::getCels(CelList& cels) const
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2014-05-02 11:28:03 -03:00
|
|
|
LayerConstIterator it = getLayerBegin();
|
|
|
|
LayerConstIterator end = getLayerEnd();
|
2009-11-17 13:12:26 +00:00
|
|
|
|
|
|
|
for (; it != end; ++it)
|
2010-09-19 00:15:44 -03:00
|
|
|
(*it)->getCels(cels);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2012-08-18 22:21:42 -03:00
|
|
|
void LayerFolder::addLayer(Layer* layer)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2009-11-17 13:12:26 +00:00
|
|
|
m_layers.push_back(layer);
|
2013-01-11 12:43:25 -03:00
|
|
|
layer->setParent(this);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2012-08-18 22:21:42 -03:00
|
|
|
void LayerFolder::removeLayer(Layer* layer)
|
2009-05-31 16:02:32 +00:00
|
|
|
{
|
2009-11-17 13:12:26 +00:00
|
|
|
LayerIterator it = std::find(m_layers.begin(), m_layers.end(), layer);
|
2010-08-03 23:33:44 -03:00
|
|
|
ASSERT(it != m_layers.end());
|
2009-11-17 13:12:26 +00:00
|
|
|
m_layers.erase(it);
|
2009-05-31 16:02:32 +00:00
|
|
|
|
2013-01-11 12:43:25 -03:00
|
|
|
layer->setParent(NULL);
|
2009-05-31 16:02:32 +00:00
|
|
|
}
|
|
|
|
|
2012-08-18 22:21:42 -03:00
|
|
|
void LayerFolder::stackLayer(Layer* layer, Layer* after)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2009-11-17 13:12:26 +00:00
|
|
|
LayerIterator it = std::find(m_layers.begin(), m_layers.end(), layer);
|
2010-08-03 23:33:44 -03:00
|
|
|
ASSERT(it != m_layers.end());
|
2009-11-17 13:12:26 +00:00
|
|
|
m_layers.erase(it);
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2009-11-17 13:12:26 +00:00
|
|
|
if (after) {
|
|
|
|
LayerIterator after_it = std::find(m_layers.begin(), m_layers.end(), after);
|
2010-08-03 23:33:44 -03:00
|
|
|
ASSERT(after_it != m_layers.end());
|
2009-11-17 13:12:26 +00:00
|
|
|
after_it++;
|
|
|
|
m_layers.insert(after_it, layer);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
2009-11-17 13:12:26 +00:00
|
|
|
else
|
|
|
|
m_layers.push_front(layer);
|
|
|
|
|
|
|
|
// TODO
|
|
|
|
// if (after) {
|
|
|
|
// JLink before = jlist_find(m_layers, after)->next;
|
|
|
|
// jlist_insert_before(m_layers, before, layer);
|
|
|
|
// }
|
|
|
|
// else
|
|
|
|
// jlist_prepend(m_layers, layer);
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
|
2012-07-08 21:09:09 -03:00
|
|
|
void layer_render(const Layer* layer, Image* image, int x, int y, FrameNumber frame)
|
2007-09-18 23:57:02 +00:00
|
|
|
{
|
2013-01-11 12:43:25 -03:00
|
|
|
if (!layer->isReadable())
|
2007-09-18 23:57:02 +00:00
|
|
|
return;
|
|
|
|
|
2013-11-09 19:59:05 -03:00
|
|
|
switch (layer->type()) {
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2013-11-09 19:59:05 -03:00
|
|
|
case OBJECT_LAYER_IMAGE: {
|
2010-09-19 00:26:33 -03:00
|
|
|
const Cel* cel = static_cast<const LayerImage*>(layer)->getCel(frame);
|
2008-09-30 21:01:54 +00:00
|
|
|
Image* src_image;
|
2007-09-18 23:57:02 +00:00
|
|
|
|
2007-11-16 20:49:40 +00:00
|
|
|
if (cel) {
|
2012-01-05 19:45:03 -03:00
|
|
|
ASSERT((cel->getImage() >= 0) &&
|
|
|
|
(cel->getImage() < layer->getSprite()->getStock()->size()));
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2012-01-05 19:45:03 -03:00
|
|
|
src_image = layer->getSprite()->getStock()->getImage(cel->getImage());
|
|
|
|
ASSERT(src_image != NULL);
|
2008-02-29 19:29:49 +00:00
|
|
|
|
2013-11-09 19:59:05 -03:00
|
|
|
src_image->setMaskColor(layer->getSprite()->getTransparentColor());
|
2011-06-25 17:12:08 -03:00
|
|
|
|
2013-11-09 19:59:05 -03:00
|
|
|
composite_image(image, src_image,
|
|
|
|
cel->getX() + x,
|
|
|
|
cel->getY() + y,
|
|
|
|
MID (0, cel->getOpacity(), 255),
|
|
|
|
static_cast<const LayerImage*>(layer)->getBlendMode());
|
2007-09-18 23:57:02 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2013-11-09 19:59:05 -03:00
|
|
|
case OBJECT_LAYER_FOLDER: {
|
2013-01-11 12:43:25 -03:00
|
|
|
LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin();
|
|
|
|
LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd();
|
2009-11-17 13:12:26 +00:00
|
|
|
|
|
|
|
for (; it != end; ++it)
|
2012-01-05 19:45:03 -03:00
|
|
|
layer_render(*it, image, x, y, frame);
|
2009-11-17 13:12:26 +00:00
|
|
|
|
2007-09-18 23:57:02 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
2013-08-05 21:20:19 -03:00
|
|
|
|
|
|
|
} // namespace raster
|