std::size_t Cel::links() const { std::size_t links = 0; Sprite* sprite = this->sprite(); for (frame_t fr=0; fr<sprite->totalFrames(); ++fr) { Cel* cel = m_layer->cel(fr); if (cel && cel != this && cel->dataRef().get() == m_data.get()) ++links; } return links; }
Cel* Cel::link() const { ASSERT(m_data); if (m_data.get() == NULL) return NULL; if (!m_data.unique()) { for (frame_t fr=0; fr<m_frame; ++fr) { Cel* possible = m_layer->cel(fr); if (possible && possible->dataRef().get() == m_data.get()) return possible; } } return NULL; }
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 write_layer(std::ostream& os, const Layer* layer) { write32(os, layer->id()); write_string(os, layer->name()); write32(os, static_cast<int>(layer->flags())); // Flags write16(os, static_cast<int>(layer->type())); // Type switch (layer->type()) { case ObjectType::LayerImage: { CelConstIterator it, begin = static_cast<const LayerImage*>(layer)->getCelBegin(); CelConstIterator end = static_cast<const LayerImage*>(layer)->getCelEnd(); // Images int images = 0; int celdatas = 0; for (it=begin; it != end; ++it) { Cel* cel = *it; if (!cel->link()) { ++images; ++celdatas; } } write16(os, images); for (it=begin; it != end; ++it) { Cel* cel = *it; if (!cel->link()) write_image(os, cel->image()); } write16(os, celdatas); for (it=begin; it != end; ++it) { Cel* cel = *it; if (!cel->link()) write_celdata(os, cel->dataRef().get()); } // Cels write16(os, static_cast<const LayerImage*>(layer)->getCelsCount()); for (it=begin; it != end; ++it) { const Cel* cel = *it; write_cel(os, cel); } break; } case ObjectType::LayerFolder: { LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin(); LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd(); // Number of sub-layers write16(os, static_cast<const LayerFolder*>(layer)->getLayersCount()); for (; it != end; ++it) write_layer(os, *it); break; } } }