void ofApp::show_merge(int play_cnt) { memcpy(tmp, recorded + image_size * play_cnt, image_size); memcpy(merged, show, image_size); bgs(tmp); image_merge(merged, tmp, 0); img.setFromPixels(merged, width, height, OF_IMAGE_COLOR); img.draw(width, height); }
void DocumentApi::pasteImage(Sprite* sprite, Cel* cel, const Image* src_image, int x, int y, int opacity) { ASSERT(cel != NULL); Image* cel_image = sprite->getStock()->getImage(cel->getImage()); Image* cel_image2 = Image::createCopy(cel_image); image_merge(cel_image2, src_image, x-cel->getX(), y-cel->getY(), opacity, BLEND_MODE_NORMAL); replaceStockImage(sprite, cel->getImage(), cel_image2); // TODO fix this, improve, avoid replacing the whole image }
void UndoTransaction::pasteImage(const Image* src_image, int x, int y, int opacity) { const Layer* layer = m_sprite->getCurrentLayer(); ASSERT(layer); ASSERT(layer->is_image()); ASSERT(layer->is_readable()); ASSERT(layer->is_writable()); Cel* cel = ((LayerImage*)layer)->getCel(m_sprite->getCurrentFrame()); ASSERT(cel); Image* cel_image = m_sprite->getStock()->getImage(cel->getImage()); Image* cel_image2 = Image::createCopy(cel_image); image_merge(cel_image2, src_image, x-cel->getX(), y-cel->getY(), opacity, BLEND_MODE_NORMAL); replaceStockImage(cel->getImage(), cel_image2); // TODO fix this, improve, avoid replacing the whole image }
void layer_render(const Layer* layer, Image* image, int x, int y, FrameNumber frame) { if (!layer->isReadable()) return; switch (layer->getType()) { case GFXOBJ_LAYER_IMAGE: { const Cel* cel = static_cast<const LayerImage*>(layer)->getCel(frame); Image* src_image; if (cel) { ASSERT((cel->getImage() >= 0) && (cel->getImage() < layer->getSprite()->getStock()->size())); src_image = layer->getSprite()->getStock()->getImage(cel->getImage()); ASSERT(src_image != NULL); src_image->mask_color = layer->getSprite()->getTransparentColor(); image_merge(image, src_image, cel->getX() + x, cel->getY() + y, MID (0, cel->getOpacity(), 255), static_cast<const LayerImage*>(layer)->getBlendMode()); } break; } case GFXOBJ_LAYER_FOLDER: { LayerConstIterator it = static_cast<const LayerFolder*>(layer)->getLayerBegin(); LayerConstIterator end = static_cast<const LayerFolder*>(layer)->getLayerEnd(); for (; it != end; ++it) layer_render(*it, image, x, y, frame); break; } } }
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)); }
void UndoTransaction::backgroundFromLayer(LayerImage* layer, int bgcolor) { ASSERT(layer); ASSERT(layer->is_image()); ASSERT(layer->is_readable()); ASSERT(layer->is_writable()); ASSERT(layer->getSprite() == m_sprite); ASSERT(m_sprite->getBackgroundLayer() == NULL); // create a temporary image to draw each frame of the new // `Background' layer UniquePtr<Image> bg_image_wrap(Image::create(m_sprite->getPixelFormat(), m_sprite->getWidth(), m_sprite->getHeight())); Image* bg_image = bg_image_wrap.get(); CelIterator it = layer->getCelBegin(); CelIterator end = layer->getCelEnd(); for (; it != end; ++it) { Cel* cel = *it; ASSERT((cel->getImage() > 0) && (cel->getImage() < m_sprite->getStock()->size())); // get the image from the sprite's stock of images Image* cel_image = m_sprite->getStock()->getImage(cel->getImage()); ASSERT(cel_image); image_clear(bg_image, bgcolor); image_merge(bg_image, cel_image, cel->getX(), cel->getY(), MID(0, cel->getOpacity(), 255), layer->getBlendMode()); // now we have to copy the new image (bg_image) to the cel... setCelPosition(cel, 0, 0); // same size of cel-image and bg-image if (bg_image->w == cel_image->w && bg_image->h == cel_image->h) { if (isEnabled()) m_undoHistory->pushUndoer(new undoers::ImageArea(m_undoHistory->getObjects(), cel_image, 0, 0, cel_image->w, cel_image->h)); image_copy(cel_image, bg_image, 0, 0); } else { replaceStockImage(cel->getImage(), Image::createCopy(bg_image)); } } // Fill all empty cels with a flat-image filled with bgcolor for (int frame=0; frame<m_sprite->getTotalFrames(); frame++) { Cel* cel = layer->getCel(frame); if (!cel) { Image* cel_image = Image::create(m_sprite->getPixelFormat(), m_sprite->getWidth(), m_sprite->getHeight()); image_clear(cel_image, bgcolor); // Add the new image in the stock int image_index = addImageInStock(cel_image); // Create the new cel and add it to the new background layer cel = new Cel(frame, image_index); addCel(layer, cel); } } configureLayerAsBackground(layer); }