mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-17 17:42:51 +00:00
- Added doc::BlendMode enum and doc::BlendFunc type - Renamed LayerImage::getBlendMode() -> blendMode() - BLEND_MODE_COPY is BlendMode::SRC now - BLEND_MODE_NORMAL is BlendMode::NORMAL now - Added app::cmd::SetLayerBlendMode
133 lines
3.5 KiB
C++
133 lines
3.5 KiB
C++
// Aseprite
|
|
// Copyright (C) 2001-2015 David Capello
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2 as
|
|
// published by the Free Software Foundation.
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "app/cmd/copy_cel.h"
|
|
|
|
#include "app/cmd/add_cel.h"
|
|
#include "app/cmd/add_frame.h"
|
|
#include "app/cmd/clear_cel.h"
|
|
#include "app/cmd/copy_rect.h"
|
|
#include "app/cmd/remove_cel.h"
|
|
#include "app/cmd/set_cel_data.h"
|
|
#include "app/cmd/unlink_cel.h"
|
|
#include "app/document.h"
|
|
#include "doc/cel.h"
|
|
#include "doc/layer.h"
|
|
#include "doc/primitives.h"
|
|
#include "doc/sprite.h"
|
|
#include "render/render.h"
|
|
|
|
namespace app {
|
|
namespace cmd {
|
|
|
|
using namespace doc;
|
|
|
|
CopyCel::CopyCel(
|
|
LayerImage* srcLayer, frame_t srcFrame,
|
|
LayerImage* dstLayer, frame_t dstFrame)
|
|
: m_srcLayer(srcLayer)
|
|
, m_dstLayer(dstLayer)
|
|
, m_srcFrame(srcFrame)
|
|
, m_dstFrame(dstFrame)
|
|
{
|
|
}
|
|
|
|
void CopyCel::onExecute()
|
|
{
|
|
LayerImage* srcLayer = static_cast<LayerImage*>(m_srcLayer.layer());
|
|
LayerImage* dstLayer = static_cast<LayerImage*>(m_dstLayer.layer());
|
|
|
|
ASSERT(srcLayer);
|
|
ASSERT(dstLayer);
|
|
|
|
Sprite* srcSprite = srcLayer->sprite();
|
|
Sprite* dstSprite = dstLayer->sprite();
|
|
ASSERT(srcSprite);
|
|
ASSERT(dstSprite);
|
|
ASSERT(m_srcFrame >= 0 && m_srcFrame < srcSprite->totalFrames());
|
|
ASSERT(m_dstFrame >= 0);
|
|
(void)srcSprite; // To avoid unused variable warning on Release mode
|
|
|
|
Cel* srcCel = srcLayer->cel(m_srcFrame);
|
|
Cel* dstCel = dstLayer->cel(m_dstFrame);
|
|
|
|
// Clear destination cel if it does exist. It'll be overriden by the
|
|
// copy of srcCel.
|
|
if (dstCel) {
|
|
if (dstCel->links())
|
|
executeAndAdd(new cmd::UnlinkCel(dstCel));
|
|
executeAndAdd(new cmd::ClearCel(dstCel));
|
|
}
|
|
|
|
// Add empty frames until newFrame
|
|
while (dstSprite->totalFrames() <= m_dstFrame)
|
|
executeAndAdd(new cmd::AddFrame(dstSprite, dstSprite->totalFrames()));
|
|
|
|
Image* srcImage = (srcCel ? srcCel->image(): NULL);
|
|
ImageRef dstImage;
|
|
dstCel = dstLayer->cel(m_dstFrame);
|
|
if (dstCel)
|
|
dstImage = dstCel->imageRef();
|
|
|
|
bool createLink =
|
|
(srcLayer == dstLayer && dstLayer->isContinuous());
|
|
|
|
// For background layer
|
|
if (dstLayer->isBackground()) {
|
|
ASSERT(dstCel);
|
|
ASSERT(dstImage);
|
|
if (!dstCel || !dstImage ||
|
|
!srcCel || !srcImage)
|
|
return;
|
|
|
|
if (createLink) {
|
|
executeAndAdd(new cmd::SetCelData(dstCel, srcCel->dataRef()));
|
|
}
|
|
else {
|
|
BlendMode blend = (srcLayer->isBackground() ?
|
|
BlendMode::SRC:
|
|
BlendMode::NORMAL);
|
|
|
|
ImageRef tmp(Image::createCopy(dstImage.get()));
|
|
render::composite_image(tmp.get(), srcImage,
|
|
srcCel->x(), srcCel->y(), 255, blend);
|
|
executeAndAdd(new cmd::CopyRect(dstImage.get(), tmp.get(), gfx::Clip(tmp->bounds())));
|
|
}
|
|
}
|
|
// For transparent layers
|
|
else {
|
|
if (dstCel)
|
|
executeAndAdd(new cmd::RemoveCel(dstCel));
|
|
|
|
if (srcCel) {
|
|
if (createLink)
|
|
dstCel = Cel::createLink(srcCel);
|
|
else
|
|
dstCel = Cel::createCopy(srcCel);
|
|
dstCel->setFrame(m_dstFrame);
|
|
|
|
executeAndAdd(new cmd::AddCel(dstLayer, dstCel));
|
|
}
|
|
}
|
|
}
|
|
|
|
void CopyCel::onFireNotifications()
|
|
{
|
|
CmdSequence::onFireNotifications();
|
|
static_cast<app::Document*>(m_dstLayer.layer()->sprite()->document())
|
|
->notifyCelCopied(
|
|
m_srcLayer.layer(), m_srcFrame,
|
|
m_dstLayer.layer(), m_dstFrame);
|
|
}
|
|
|
|
} // namespace cmd
|
|
} // namespace app
|