void clipboard::cut(ContextWriter& writer) { ASSERT(writer.document() != NULL); ASSERT(writer.sprite() != NULL); ASSERT(writer.layer() != NULL); if (!copy_from_document(*writer.location())) { Console console; console.printf("Can't copying an image portion from the current layer\n"); } else { { UndoTransaction undoTransaction(writer.context(), "Cut"); DocumentApi api(writer.document()->getApi()); api.clearMask(writer.layer(), writer.cel(), app_get_color_to_clear_layer(writer.layer())); api.deselectMask(); undoTransaction.commit(); } writer.document()->generateMaskBoundaries(); update_screen_for_document(writer.document()); } }
RotateCanvasJob(const ContextReader& reader, int angle) : Job("Rotate Canvas") , m_writer(reader) , m_document(m_writer.document()) , m_sprite(m_writer.sprite()) { m_angle = angle; }
SpriteSizeJob(const ContextReader& reader, int new_width, int new_height, ResizeMethod resize_method) : Job("Sprite Size") , m_writer(reader) , m_document(m_writer.document()) , m_sprite(m_writer.sprite()) { m_new_width = new_width; m_new_height = new_height; m_resize_method = resize_method; }
RotateJob(const ContextReader& reader, int angle, const CelList& cels, bool rotateSprite) : Job("Rotate Canvas") , m_writer(reader) , m_document(m_writer.document()) , m_sprite(m_writer.sprite()) , m_cels(cels) , m_rotateSprite(rotateSprite) { m_angle = angle; }
void move_cel(ContextWriter& writer) { Document* document = writer.document(); Sprite* sprite = writer.sprite(); Cel *src_cel, *dst_cel; ASSERT(src_layer != NULL); ASSERT(dst_layer != NULL); ASSERT(src_frame >= 0 && src_frame < sprite->getTotalFrames()); ASSERT(dst_frame >= 0 && dst_frame < sprite->getTotalFrames()); if (src_layer->isBackground()) { copy_cel(writer); return; } src_cel = static_cast<LayerImage*>(src_layer)->getCel(src_frame); dst_cel = static_cast<LayerImage*>(dst_layer)->getCel(dst_frame); UndoTransaction undo(writer.context(), "Move Cel", undo::ModifyDocument); /* remove the 'dst_cel' (if it exists) because it must be replaced with 'src_cel' */ if ((dst_cel != NULL) && (!dst_layer->isBackground() || src_cel != NULL)) remove_cel(sprite, undo, static_cast<LayerImage*>(dst_layer), dst_cel); /* move the cel in the same layer */ if (src_cel != NULL) { if (src_layer == dst_layer) { if (undo.isEnabled()) undo.pushUndoer(new undoers::SetCelFrame(undo.getObjects(), src_cel)); src_cel->setFrame(dst_frame); } /* move the cel in different layers */ else { if (undo.isEnabled()) undo.pushUndoer(new undoers::RemoveCel(undo.getObjects(), src_layer, src_cel)); static_cast<LayerImage*>(src_layer)->removeCel(src_cel); src_cel->setFrame(dst_frame); /* if we are moving a cel from a transparent layer to the background layer, we have to clear the background of the image */ if (!src_layer->isBackground() && dst_layer->isBackground()) { Image *src_image = sprite->getStock()->getImage(src_cel->getImage()); Image *dst_image = image_crop(src_image, -src_cel->getX(), -src_cel->getY(), sprite->getWidth(), sprite->getHeight(), 0); if (undo.isEnabled()) { undo.pushUndoer(new undoers::ReplaceImage(undo.getObjects(), sprite->getStock(), src_cel->getImage())); undo.pushUndoer(new undoers::SetCelPosition(undo.getObjects(), src_cel)); undo.pushUndoer(new undoers::SetCelOpacity(undo.getObjects(), src_cel)); } image_clear(dst_image, app_get_color_to_clear_layer(dst_layer)); image_merge(dst_image, src_image, src_cel->getX(), src_cel->getY(), 255, BLEND_MODE_NORMAL); src_cel->setPosition(0, 0); src_cel->setOpacity(255); sprite->getStock()->replaceImage(src_cel->getImage(), dst_image); image_free(src_image); } if (undo.isEnabled()) undo.pushUndoer(new undoers::AddCel(undo.getObjects(), dst_layer, src_cel)); static_cast<LayerImage*>(dst_layer)->addCel(src_cel); } } undo.commit(); document->notifyCelMoved(src_layer, src_frame, dst_layer, dst_frame); set_frame_to_handle(NULL, FrameNumber(0), NULL, FrameNumber(0)); }
void copy_cel(ContextWriter& writer) { Document* document = writer.document(); Sprite* sprite = writer.sprite(); UndoTransaction undo(writer.context(), "Move Cel", undo::ModifyDocument); Cel *src_cel, *dst_cel; ASSERT(src_layer != NULL); ASSERT(dst_layer != NULL); ASSERT(src_frame >= 0 && src_frame < sprite->getTotalFrames()); ASSERT(dst_frame >= 0 && dst_frame < sprite->getTotalFrames()); src_cel = static_cast<LayerImage*>(src_layer)->getCel(src_frame); dst_cel = static_cast<LayerImage*>(dst_layer)->getCel(dst_frame); // Remove the 'dst_cel' (if it exists) because it must be replaced // with 'src_cel' if ((dst_cel != NULL) && (!dst_layer->isBackground() || src_cel != NULL)) remove_cel(sprite, undo, static_cast<LayerImage*>(dst_layer), dst_cel); // Move the cel in the same layer. if (src_cel != NULL) { Image *src_image = sprite->getStock()->getImage(src_cel->getImage()); Image *dst_image; int image_index; int dst_cel_x; int dst_cel_y; int dst_cel_opacity; // If we are moving a cel from a transparent layer to the // background layer, we have to clear the background of the image. if (!src_layer->isBackground() && dst_layer->isBackground()) { dst_image = image_crop(src_image, -src_cel->getX(), -src_cel->getY(), sprite->getWidth(), sprite->getHeight(), 0); image_clear(dst_image, app_get_color_to_clear_layer(dst_layer)); image_merge(dst_image, src_image, src_cel->getX(), src_cel->getY(), 255, BLEND_MODE_NORMAL); dst_cel_x = 0; dst_cel_y = 0; dst_cel_opacity = 255; } else { dst_image = Image::createCopy(src_image); dst_cel_x = src_cel->getX(); dst_cel_y = src_cel->getY(); dst_cel_opacity = src_cel->getOpacity(); } // Add the image in the stock image_index = sprite->getStock()->addImage(dst_image); if (undo.isEnabled()) undo.pushUndoer(new undoers::AddImage(undo.getObjects(), sprite->getStock(), image_index)); // Create the new cel dst_cel = new Cel(dst_frame, image_index); dst_cel->setPosition(dst_cel_x, dst_cel_y); dst_cel->setOpacity(dst_cel_opacity); if (undo.isEnabled()) undo.pushUndoer(new undoers::AddCel(undo.getObjects(), dst_layer, dst_cel)); static_cast<LayerImage*>(dst_layer)->addCel(dst_cel); } undo.commit(); document->notifyCelCopied(src_layer, src_frame, dst_layer, dst_frame); set_frame_to_handle(NULL, FrameNumber(0), NULL, FrameNumber(0)); }
/** * [working thread] */ virtual void onJob() { UndoTransaction undoTransaction(m_writer.context(), "Sprite Size"); DocumentApi api = m_writer.document()->getApi(); // Get all sprite cels CelList cels; m_sprite->getCels(cels); // For each cel... int progress = 0; for (CelIterator it = cels.begin(); it != cels.end(); ++it, ++progress) { Cel* cel = *it; // Change its location api.setCelPosition(m_sprite, cel, scale_x(cel->x()), scale_y(cel->y())); // Get cel's image Image* image = cel->image(); if (!image) continue; // Resize the image int w = scale_x(image->width()); int h = scale_y(image->height()); Image* new_image = Image::create(image->pixelFormat(), MAX(1, w), MAX(1, h)); doc::algorithm::fixup_image_transparent_colors(image); doc::algorithm::resize_image(image, new_image, m_resize_method, m_sprite->getPalette(cel->frame()), m_sprite->getRgbMap(cel->frame())); api.replaceStockImage(m_sprite, cel->imageIndex(), new_image); jobProgress((float)progress / cels.size()); // cancel all the operation? if (isCanceled()) return; // UndoTransaction destructor will undo all operations } // Resize mask if (m_document->isMaskVisible()) { base::UniquePtr<Image> old_bitmap (crop_image(m_document->mask()->bitmap(), -1, -1, m_document->mask()->bitmap()->width()+2, m_document->mask()->bitmap()->height()+2, 0)); int w = scale_x(old_bitmap->width()); int h = scale_y(old_bitmap->height()); base::UniquePtr<Mask> new_mask(new Mask); new_mask->replace(scale_x(m_document->mask()->bounds().x-1), scale_y(m_document->mask()->bounds().y-1), MAX(1, w), MAX(1, h)); algorithm::resize_image(old_bitmap, new_mask->bitmap(), m_resize_method, m_sprite->getPalette(FrameNumber(0)), // Ignored m_sprite->getRgbMap(FrameNumber(0))); // Ignored // Reshrink new_mask->intersect(new_mask->bounds()); // Copy new mask api.copyToCurrentMask(new_mask); // Regenerate mask m_document->resetTransformation(); m_document->generateMaskBoundaries(); } // resize sprite api.setSpriteSize(m_sprite, m_new_width, m_new_height); // commit changes undoTransaction.commit(); }