void ExpandCelCanvas::validateSourceCanvas(const gfx::Region& rgn) { getSourceCanvas(); gfx::Region rgnToValidate(rgn); rgnToValidate.offset(-m_bounds.getOrigin()); rgnToValidate.createSubtraction(rgnToValidate, m_validSrcRegion); rgnToValidate.createIntersection(rgnToValidate, gfx::Region(m_srcImage->bounds())); if (m_celImage) { gfx::Region rgnToClear; rgnToClear.createSubtraction(rgnToValidate, gfx::Region(m_celImage->bounds() .offset(m_origCelPos) .offset(-m_bounds.getOrigin()))); for (const auto& rc : rgnToClear) fill_rect(m_srcImage, rc, m_srcImage->maskColor()); for (const auto& rc : rgnToValidate) m_srcImage->copy(m_celImage, rc.x, rc.y, rc.x+m_bounds.x-m_origCelPos.x, rc.y+m_bounds.y-m_origCelPos.y, rc.w, rc.h); } else { for (const auto& rc : rgnToValidate) fill_rect(m_srcImage, rc, m_srcImage->maskColor()); } m_validSrcRegion.createUnion(m_validSrcRegion, rgnToValidate); }
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; }