void Document::copyLayerContent(const Layer* sourceLayer0, Document* destDoc, Layer* destLayer0) const { // Copy the layer name destLayer0->setName(sourceLayer0->name()); if (sourceLayer0->isImage() && destLayer0->isImage()) { const LayerImage* sourceLayer = static_cast<const LayerImage*>(sourceLayer0); LayerImage* destLayer = static_cast<LayerImage*>(destLayer0); // copy cels CelConstIterator it = sourceLayer->getCelBegin(); CelConstIterator end = sourceLayer->getCelEnd(); for (; it != end; ++it) { const Cel* sourceCel = *it; if (sourceCel->frame() > destLayer->sprite()->lastFrame()) break; base::UniquePtr<Cel> newCel(new Cel(*sourceCel)); const Image* sourceImage = sourceCel->image(); ASSERT(sourceImage != NULL); Image* newImage = Image::createCopy(sourceImage); newCel->setImage(destLayer->sprite()->stock()->addImage(newImage)); destLayer->addCel(newCel); newCel.release(); } } else if (sourceLayer0->isFolder() && destLayer0->isFolder()) { const LayerFolder* sourceLayer = static_cast<const LayerFolder*>(sourceLayer0); LayerFolder* destLayer = static_cast<LayerFolder*>(destLayer0); LayerConstIterator it = sourceLayer->getLayerBegin(); LayerConstIterator end = sourceLayer->getLayerEnd(); for (; it != end; ++it) { Layer* sourceChild = *it; base::UniquePtr<Layer> destChild(NULL); if (sourceChild->isImage()) { destChild.reset(new LayerImage(destLayer->sprite())); copyLayerContent(sourceChild, destDoc, destChild); } else if (sourceChild->isFolder()) { destChild.reset(new LayerFolder(destLayer->sprite())); copyLayerContent(sourceChild, destDoc, destChild); } else { ASSERT(false); } ASSERT(destChild != NULL); // Add the new layer in the sprite. Layer* newLayer = destChild.release(); Layer* afterThis = destLayer->getLastLayer(); destLayer->addLayer(newLayer); destChild.release(); destLayer->stackLayer(newLayer, afterThis); } } else { ASSERT(false && "Trying to copy two incompatible layers"); } }
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 Document::copyLayerContent(const Layer* sourceLayer0, Document* destDoc, Layer* destLayer0) const { LayerFlags dstFlags = sourceLayer0->flags(); // Remove the "background" flag if the destDoc already has a background layer. if (((int)dstFlags & (int)LayerFlags::Background) == (int)LayerFlags::Background && (destDoc->sprite()->backgroundLayer())) { dstFlags = (LayerFlags)((int)dstFlags & ~(int)(LayerFlags::BackgroundLayerFlags)); } // Copy the layer name destLayer0->setName(sourceLayer0->name()); destLayer0->setFlags(dstFlags); if (sourceLayer0->isImage() && destLayer0->isImage()) { const LayerImage* sourceLayer = static_cast<const LayerImage*>(sourceLayer0); LayerImage* destLayer = static_cast<LayerImage*>(destLayer0); // copy cels CelConstIterator it = sourceLayer->getCelBegin(); CelConstIterator end = sourceLayer->getCelEnd(); std::map<ObjectId, Cel*> linked; for (; it != end; ++it) { const Cel* sourceCel = *it; if (sourceCel->frame() > destLayer->sprite()->lastFrame()) break; base::UniquePtr<Cel> newCel; auto it = linked.find(sourceCel->data()->id()); if (it != linked.end()) { newCel.reset(Cel::createLink(it->second)); newCel->setFrame(sourceCel->frame()); } else { newCel.reset(Cel::createCopy(sourceCel)); linked.insert(std::make_pair(sourceCel->data()->id(), newCel.get())); } destLayer->addCel(newCel); newCel.release(); } } else if (sourceLayer0->isFolder() && destLayer0->isFolder()) { const LayerFolder* sourceLayer = static_cast<const LayerFolder*>(sourceLayer0); LayerFolder* destLayer = static_cast<LayerFolder*>(destLayer0); LayerConstIterator it = sourceLayer->getLayerBegin(); LayerConstIterator end = sourceLayer->getLayerEnd(); for (; it != end; ++it) { Layer* sourceChild = *it; base::UniquePtr<Layer> destChild(NULL); if (sourceChild->isImage()) { destChild.reset(new LayerImage(destLayer->sprite())); copyLayerContent(sourceChild, destDoc, destChild); } else if (sourceChild->isFolder()) { destChild.reset(new LayerFolder(destLayer->sprite())); copyLayerContent(sourceChild, destDoc, destChild); } else { ASSERT(false); } ASSERT(destChild != NULL); // Add the new layer in the sprite. Layer* newLayer = destChild.release(); Layer* afterThis = destLayer->getLastLayer(); destLayer->addLayer(newLayer); destChild.release(); destLayer->stackLayer(newLayer, afterThis); } } else { ASSERT(false && "Trying to copy two incompatible layers"); } }