void UndoTransaction::removeFrameOfLayer(Layer* layer, int frame) { ASSERT(layer); ASSERT(frame >= 0); switch (layer->getType()) { case GFXOBJ_LAYER_IMAGE: if (Cel* cel = static_cast<LayerImage*>(layer)->getCel(frame)) removeCel(static_cast<LayerImage*>(layer), cel); for (++frame; frame<m_sprite->getTotalFrames(); ++frame) if (Cel* cel = static_cast<LayerImage*>(layer)->getCel(frame)) setCelFramePosition(cel, cel->getFrame()-1); break; case GFXOBJ_LAYER_FOLDER: { LayerIterator it = static_cast<LayerFolder*>(layer)->get_layer_begin(); LayerIterator end = static_cast<LayerFolder*>(layer)->get_layer_end(); for (; it != end; ++it) removeFrameOfLayer(*it, frame); break; } } }
// Does the hard part of removing a frame: Removes all cels located in // the given frame, and moves all following cels one frame position back. void DocumentApi::removeFrameOfLayer(Layer* layer, FrameNumber frame) { ASSERT(layer); ASSERT(frame >= 0); Sprite* sprite = layer->getSprite(); switch (layer->getType()) { case GFXOBJ_LAYER_IMAGE: if (Cel* cel = static_cast<LayerImage*>(layer)->getCel(frame)) removeCel(static_cast<LayerImage*>(layer), cel); for (++frame; frame<sprite->getTotalFrames(); ++frame) if (Cel* cel = static_cast<LayerImage*>(layer)->getCel(frame)) setCelFramePosition(sprite, cel, cel->getFrame().previous()); break; case GFXOBJ_LAYER_FOLDER: { LayerIterator it = static_cast<LayerFolder*>(layer)->getLayerBegin(); LayerIterator end = static_cast<LayerFolder*>(layer)->getLayerEnd(); for (; it != end; ++it) removeFrameOfLayer(*it, frame); break; } } }
void LayerImage::moveCel(Cel* cel, FrameNumber frame) { removeCel(cel); cel->setFrame(frame); addCel(cel); }
// clears the mask region in the current sprite with the specified background color void UndoTransaction::clearMask(int bgcolor) { Cel* cel = getCurrentCel(); if (!cel) return; Image* image = getCelImage(cel); if (!image) return; Mask* mask = m_document->getMask(); // If the mask is empty or is not visible then we have to clear the // entire image in the cel. if (!m_document->isMaskVisible()) { // If the layer is the background then we clear the image. if (m_sprite->getCurrentLayer()->is_background()) { if (isEnabled()) m_undoHistory->pushUndoer(new undoers::ImageArea(m_undoHistory->getObjects(), image, 0, 0, image->w, image->h)); // clear all image_clear(image, bgcolor); } // If the layer is transparent we can remove the cel (and its // associated image). else { removeCel(static_cast<LayerImage*>(m_sprite->getCurrentLayer()), cel); } } else { int offset_x = mask->getBounds().x-cel->getX(); int offset_y = mask->getBounds().y-cel->getY(); int u, v, putx, puty; int x1 = MAX(0, offset_x); int y1 = MAX(0, offset_y); int x2 = MIN(image->w-1, offset_x+mask->getBounds().w-1); int y2 = MIN(image->h-1, offset_y+mask->getBounds().h-1); // do nothing if (x1 > x2 || y1 > y2) return; if (isEnabled()) m_undoHistory->pushUndoer(new undoers::ImageArea(m_undoHistory->getObjects(), image, x1, y1, x2-x1+1, y2-y1+1)); // clear the masked zones for (v=0; v<mask->getBounds().h; v++) { div_t d = div(0, 8); uint8_t* address = ((uint8_t**)mask->getBitmap()->line)[v]+d.quot; for (u=0; u<mask->getBounds().w; u++) { if ((*address & (1<<d.rem))) { putx = u + offset_x; puty = v + offset_y; image_putpixel(image, putx, puty, bgcolor); } _image_bitmap_next_bit(d, address); } } } }