void ExpandCelCanvas::commit() { ASSERT(!m_closed); ASSERT(!m_committed); // Was the cel created in the start of the tool-loop? if (m_celCreated) { ASSERT(m_cel); ASSERT(!m_celImage); // Validate the whole m_dstImage (invalid areas are cleared, as we // don't have a m_celImage) validateDestCanvas(gfx::Region(m_bounds)); // We can temporary remove the cel. static_cast<LayerImage*>(m_layer)->removeCel(m_cel); // Add a copy of m_dstImage in the sprite's image stock ImageRef newImage(Image::createCopy(m_dstImage.get())); m_cel->data()->setImage(newImage); // And finally we add the cel again in the layer. m_transaction.execute(new cmd::AddCel(m_layer, m_cel)); } else if (m_celImage) { // If the size of each image is the same, we can create an undo // with only the differences between both images. if (m_cel->position() == m_origCelPos && m_bounds.origin() == m_origCelPos && m_celImage->width() == m_dstImage->width() && m_celImage->height() == m_dstImage->height()) { int dx = -m_bounds.x + m_origCelPos.x; int dy = -m_bounds.y + m_origCelPos.y; if ((m_flags & UseModifiedRegionAsUndoInfo) != UseModifiedRegionAsUndoInfo) { // TODO Reduce m_validDstRegion to modified areas between // m_celImage and m_dstImage } // Copy the destination to the cel image. m_transaction.execute(new cmd::CopyRegion( m_celImage.get(), m_dstImage.get(), m_validDstRegion, dx, dy)); } // If the size of both images are different, we have to // replace the entire image. else { if (m_cel->position() != m_origCelPos) { gfx::Point newPos = m_cel->position(); m_cel->setPosition(m_origCelPos); m_transaction.execute(new cmd::SetCelPosition(m_cel, newPos.x, newPos.y)); } // Validate the whole m_dstImage copying invalid areas from m_celImage validateDestCanvas(gfx::Region(m_bounds)); // Replace the image in the stock. We need to create a copy of // image because m_dstImage's ImageBuffer cannot be shared. ImageRef newImage(Image::createCopy(m_dstImage.get())); m_transaction.execute(new cmd::ReplaceImage( m_sprite, m_celImage, newImage)); } } else { ASSERT(false); } m_committed = true; }
void ExpandCelCanvas::commit() { ASSERT(!m_closed); ASSERT(!m_committed); // Was the cel created in the start of the tool-loop? if (m_celCreated) { ASSERT(m_cel); ASSERT(!m_celImage); // Validate the whole m_dstImage (invalid areas are cleared, as we // don't have a m_celImage) validateDestCanvas(gfx::Region(m_bounds)); // Add a copy of m_dstImage in the sprite's image stock m_cel->setImage(m_sprite->stock()->addImage( Image::createCopy(m_dstImage))); // Is the undo enabled?. if (m_undo.isEnabled()) { // We can temporary remove the cel. static_cast<LayerImage*>(m_layer)->removeCel(m_cel); // We create the undo information (for the new m_celImage // in the stock and the new cel in the layer)... m_undo.pushUndoer(new undoers::AddImage(m_undo.getObjects(), m_sprite->stock(), m_cel->imageIndex())); m_undo.pushUndoer(new undoers::AddCel(m_undo.getObjects(), m_layer, m_cel)); // And finally we add the cel again in the layer. static_cast<LayerImage*>(m_layer)->addCel(m_cel); } } else if (m_celImage) { // If the size of each image is the same, we can create an undo // with only the differences between both images. if (m_cel->position() == m_origCelPos && m_bounds.getOrigin() == m_origCelPos && m_celImage->width() == m_dstImage->width() && m_celImage->height() == m_dstImage->height()) { // Add to the undo history the differences between m_celImage and m_dstImage if (m_undo.isEnabled()) { if ((m_flags & UseModifiedRegionAsUndoInfo) == UseModifiedRegionAsUndoInfo) { m_undo.pushUndoer(new undoers::ModifiedRegion( m_undo.getObjects(), m_celImage, m_validDstRegion)); } else { Dirty dirty(m_celImage, m_dstImage, m_validDstRegion); dirty.saveImagePixels(m_celImage); m_undo.pushUndoer(new undoers::DirtyArea( m_undo.getObjects(), m_celImage, &dirty)); } } // Copy the destination to the cel image. copyValidDestToOriginalCel(); } // If the size of both images are different, we have to // replace the entire image. else { if (m_undo.isEnabled()) { if (m_cel->position() != m_origCelPos) { gfx::Point newPos = m_cel->position(); m_cel->setPosition(m_origCelPos); m_undo.pushUndoer(new undoers::SetCelPosition(m_undo.getObjects(), m_cel)); m_cel->setPosition(newPos); } m_undo.pushUndoer(new undoers::ReplaceImage(m_undo.getObjects(), m_sprite->stock(), m_cel->imageIndex())); } // Validate the whole m_dstImage copying invalid areas from m_celImage validateDestCanvas(gfx::Region(m_bounds)); // Replace the image in the stock. We need to create a copy of // image because m_dstImage's ImageBuffer cannot be shared. m_sprite->stock()->replaceImage(m_cel->imageIndex(), Image::createCopy(m_dstImage)); // Destroy the old cel image. delete m_celImage; } } else { ASSERT(false); } m_committed = true; }
void ExpandCelCanvas::commit() { ASSERT(!m_closed); ASSERT(!m_committed); if (!m_layer) { m_committed = true; return; } // Was the cel created in the start of the tool-loop? if (m_celCreated) { ASSERT(m_cel); ASSERT(!m_celImage); // Validate the whole m_dstImage (invalid areas are cleared, as we // don't have a m_celImage) validateDestCanvas(gfx::Region(m_bounds)); // We can temporary remove the cel. if (m_layer->isImage()) { static_cast<LayerImage*>(m_layer)->removeCel(m_cel); // Add a copy of m_dstImage in the sprite's image stock gfx::Rect trimBounds = getTrimDstImageBounds(); if (!trimBounds.isEmpty()) { ImageRef newImage(trimDstImage(trimBounds)); ASSERT(newImage); m_cel->data()->setImage(newImage); m_cel->setPosition(m_cel->position() + trimBounds.origin()); // And finally we add the cel again in the layer. m_transaction.execute(new cmd::AddCel(m_layer, m_cel)); } } // We are selecting inside a layer group... else { // Just delete the created layer delete m_cel; m_cel = nullptr; } } else if (m_celImage) { // Restore cel position to its original position m_cel->setPosition(m_origCelPos); ASSERT(m_cel->image() == m_celImage.get()); gfx::Region* regionToPatch = &m_validDstRegion; gfx::Region reduced; if (m_canCompareSrcVsDst) { ASSERT(gfx::Region().createSubtraction(m_validDstRegion, m_validSrcRegion).isEmpty()); for (gfx::Rect rc : m_validDstRegion) { if (algorithm::shrink_bounds2(getSourceCanvas(), getDestCanvas(), rc, rc)) { reduced |= gfx::Region(rc); } } regionToPatch = &reduced; } if (m_layer->isBackground()) { m_transaction.execute( new cmd::CopyRegion( m_cel->image(), m_dstImage.get(), *regionToPatch, m_bounds.origin())); } else { m_transaction.execute( new cmd::PatchCel( m_cel, m_dstImage.get(), *regionToPatch, m_bounds.origin())); } } else { ASSERT(false); } m_committed = true; }