Example #1
0
void UndoTransaction::flattenLayers(int bgcolor)
{
  Image* cel_image;
  Cel* cel;
  int frame;

  // create a temporary image
  UniquePtr<Image> image_wrap(Image::create(m_sprite->getPixelFormat(),
                                            m_sprite->getWidth(),
                                            m_sprite->getHeight()));
  Image* image = image_wrap.get();

  /* get the background layer from the sprite */
  LayerImage* background = m_sprite->getBackgroundLayer();
  if (!background) {
    /* if there aren't a background layer we must to create the background */
    background = new LayerImage(m_sprite);

    if (isEnabled())
      m_undoHistory->pushUndoer(new undoers::AddLayer(m_undoHistory->getObjects(),
          m_sprite->getFolder(), background));

    m_sprite->getFolder()->add_layer(background);

    if (isEnabled())
      m_undoHistory->pushUndoer(new undoers::MoveLayer(m_undoHistory->getObjects(),
          background));

    background->configureAsBackground();
  }

  /* copy all frames to the background */
  for (frame=0; frame<m_sprite->getTotalFrames(); frame++) {
    /* clear the image and render this frame */
    image_clear(image, bgcolor);
    layer_render(m_sprite->getFolder(), image, 0, 0, frame);

    cel = background->getCel(frame);
    if (cel) {
      cel_image = m_sprite->getStock()->getImage(cel->getImage());
      ASSERT(cel_image != NULL);

      /* we have to save the current state of `cel_image' in the undo */
      if (isEnabled()) {
        Dirty* dirty = new Dirty(cel_image, image);
        dirty->saveImagePixels(cel_image);
        m_undoHistory->pushUndoer(new undoers::DirtyArea(
            m_undoHistory->getObjects(), cel_image, dirty));
        delete dirty;
      }
    }
    else {
      /* if there aren't a cel in this frame in the background, we
         have to create a copy of the image for the new cel */
      cel_image = Image::createCopy(image);
      /* TODO error handling: if (!cel_image) { ... } */

      /* here we create the new cel (with the new image `cel_image') */
      cel = new Cel(frame, m_sprite->getStock()->addImage(cel_image));
      /* TODO error handling: if (!cel) { ... } */

      /* and finally we add the cel in the background */
      background->addCel(cel);
    }

    image_copy(cel_image, image, 0, 0);
  }

  /* select the background */
  if (m_sprite->getCurrentLayer() != background) {
    if (isEnabled())
      m_undoHistory->pushUndoer(new undoers::SetCurrentLayer(
          m_undoHistory->getObjects(), m_sprite));

    m_sprite->setCurrentLayer(background);
  }

  // Remove old layers.
  LayerList layers = m_sprite->getFolder()->get_layers_list();
  LayerIterator it = layers.begin();
  LayerIterator end = layers.end();

  for (; it != end; ++it) {
    if (*it != background) {
      Layer* old_layer = *it;

      // Remove the layer
      if (isEnabled())
        m_undoHistory->pushUndoer(new undoers::RemoveLayer(m_undoHistory->getObjects(),
            old_layer));

      m_sprite->getFolder()->remove_layer(old_layer);

      // Destroy the layer
      delete old_layer;
    }
  }
}
Example #2
0
void DocumentApi::flattenLayers(Sprite* sprite, int bgcolor)
{
  Image* cel_image;
  Cel* cel;

  DocumentUndo* undo = m_document->getUndo();

  // Create a temporary image.
  UniquePtr<Image> image_wrap(Image::create(sprite->getPixelFormat(),
                                            sprite->getWidth(),
                                            sprite->getHeight()));
  Image* image = image_wrap.get();

  // Get the background layer from the sprite.
  LayerImage* background = sprite->getBackgroundLayer();
  if (!background) {
    // If there aren't a background layer we must to create the background.
    background = new LayerImage(sprite);

    addLayer(sprite->getFolder(), background, NULL);
    configureLayerAsBackground(background);
  }

  // Copy all frames to the background.
  for (FrameNumber frame(0); frame<sprite->getTotalFrames(); ++frame) {
    // Clear the image and render this frame.
    image_clear(image, bgcolor);
    layer_render(sprite->getFolder(), image, 0, 0, frame);

    cel = background->getCel(frame);
    if (cel) {
      cel_image = sprite->getStock()->getImage(cel->getImage());
      ASSERT(cel_image != NULL);

      // We have to save the current state of `cel_image' in the undo.
      if (undo->isEnabled()) {
        Dirty* dirty = new Dirty(cel_image, image);
        dirty->saveImagePixels(cel_image);
        m_undoers->pushUndoer(new undoers::DirtyArea(
            getObjects(), cel_image, dirty));
        delete dirty;
      }
    }
    else {
      // If there aren't a cel in this frame in the background, we
      // have to create a copy of the image for the new cel.
      cel_image = Image::createCopy(image);
      // TODO error handling: if createCopy throws

      // Here we create the new cel (with the new image `cel_image').
      cel = new Cel(frame, sprite->getStock()->addImage(cel_image));
      // TODO error handling: if new Cel throws

      // And finally we add the cel in the background.
      background->addCel(cel);
    }

    image_copy(cel_image, image, 0, 0);
  }

  // Delete old layers.
  LayerList layers = sprite->getFolder()->getLayersList();
  LayerIterator it = layers.begin();
  LayerIterator end = layers.end();
  for (; it != end; ++it)
    if (*it != background)
      removeLayer(*it);
}