예제 #1
0
void FlattenLayers::onExecute()
{
  Sprite* sprite = this->sprite();
  auto doc = static_cast<Doc*>(sprite->document());

  // Create a temporary image.
  ImageRef image(Image::create(sprite->pixelFormat(),
      sprite->width(),
      sprite->height()));

  LayerImage* flatLayer;  // The layer onto which everything will be flattened.
  color_t     bgcolor;    // The background color to use for flatLayer.

  flatLayer = sprite->backgroundLayer();
  if (flatLayer && flatLayer->isVisible()) {
    // There exists a visible background layer, so we will flatten onto that.
    bgcolor = doc->bgColor(flatLayer);
  }
  else {
    // Create a new transparent layer to flatten everything onto.
    flatLayer = new LayerImage(sprite);
    ASSERT(flatLayer->isVisible());
    executeAndAdd(new cmd::AddLayer(sprite->root(), flatLayer, nullptr));
    executeAndAdd(new cmd::SetLayerName(flatLayer, "Flattened"));
    bgcolor = sprite->transparentColor();
  }

  render::Render render;
  render.setBgType(render::BgType::NONE);

  // Copy all frames to the background.
  for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
    // Clear the image and render this frame.
    clear_image(image.get(), bgcolor);
    render.renderSprite(image.get(), sprite, frame);

    // TODO Keep cel links when possible

    ImageRef cel_image;
    Cel* cel = flatLayer->cel(frame);
    if (cel) {
      if (cel->links())
        executeAndAdd(new cmd::UnlinkCel(cel));

      cel_image = cel->imageRef();
      ASSERT(cel_image);

      executeAndAdd(new cmd::CopyRect(cel_image.get(), image.get(),
          gfx::Clip(0, 0, image->bounds())));
    }
    else {
      cel_image.reset(Image::createCopy(image.get()));
      cel = new Cel(frame, cel_image);
      flatLayer->addCel(cel);
    }
  }

  // Delete old layers.
  LayerList layers = sprite->root()->layers();
  for (Layer* layer : layers)
    if (layer != flatLayer)
      executeAndAdd(new cmd::RemoveLayer(layer));
}
예제 #2
0
void BackgroundFromLayer::onExecute()
{
  Layer* layer = this->layer();
  Sprite* sprite = layer->sprite();
  auto doc = static_cast<Doc*>(sprite->document());
  color_t bgcolor = doc->bgColor();

  // Create a temporary image to draw each cel of the new Background
  // layer.
  ImageRef bg_image(Image::create(sprite->pixelFormat(),
      sprite->width(),
      sprite->height()));

  CelList cels;
  layer->getCels(cels);
  for (Cel* cel : cels) {
    Image* cel_image = cel->image();
    ASSERT(cel_image);

    clear_image(bg_image.get(), bgcolor);
    render::composite_image(
      bg_image.get(), cel_image,
      sprite->palette(cel->frame()),
      cel->x(), cel->y(),
      MID(0, cel->opacity(), 255),
      static_cast<LayerImage*>(layer)->blendMode());

    // now we have to copy the new image (bg_image) to the cel...
    executeAndAdd(new cmd::SetCelPosition(cel, 0, 0));

    // change opacity to 255
    if (cel->opacity() < 255)
      executeAndAdd(new cmd::SetCelOpacity(cel, 255));

    // Same size of cel image and background image, we can just
    // replace pixels.
    if (bg_image->width() == cel_image->width() &&
        bg_image->height() == cel_image->height()) {
      executeAndAdd(new CopyRect(cel_image, bg_image.get(),
          gfx::Clip(0, 0, cel_image->bounds())));
    }
    // In other case we have to replace the whole image (this is the
    // most common case, a smaller transparent cel that is converted
    // to a canvas size cel in the background)
    else {
      ImageRef bg_image2(Image::createCopy(bg_image.get()));
      executeAndAdd(new cmd::ReplaceImage(sprite, cel->imageRef(), bg_image2));
    }
  }

  // Fill all empty cels with a flat image filled with bgcolor
  for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
    Cel* cel = layer->cel(frame);
    if (!cel) {
      ImageRef cel_image(Image::create(sprite->pixelFormat(),
          sprite->width(), sprite->height()));
      clear_image(cel_image.get(), bgcolor);

      // Create the new cel and add it to the new background layer
      cel = new Cel(frame, cel_image);
      executeAndAdd(new cmd::AddCel(layer, cel));
    }
  }

  executeAndAdd(new cmd::ConfigureBackground(layer));
}
예제 #3
0
void BackgroundFromLayer::onExecute()
{
  Layer* layer = this->layer();
  Sprite* sprite = layer->sprite();
  app::Document* doc = static_cast<app::Document*>(sprite->document());
  color_t bgcolor = doc->bgColor();

  // create a temporary image to draw each frame of the new
  // `Background' layer
  ImageRef bg_image(Image::create(sprite->pixelFormat(),
      sprite->width(),
      sprite->height()));

  CelList cels;
  layer->getCels(cels);
  for (Cel* cel : cels) {
    // get the image from the sprite's stock of images
    Image* cel_image = cel->image();
    ASSERT(cel_image);

    clear_image(bg_image.get(), bgcolor);
    render::composite_image(
      bg_image.get(), cel_image,
      sprite->palette(cel->frame()),
      cel->x(), cel->y(),
      MID(0, cel->opacity(), 255),
      static_cast<LayerImage*>(layer)->blendMode());

    // now we have to copy the new image (bg_image) to the cel...
    executeAndAdd(new cmd::SetCelPosition(cel, 0, 0));

    // change opacity to 255
    if (cel->opacity() < 255)
      executeAndAdd(new cmd::SetCelOpacity(cel, 255));

    // same size of cel-image and bg-image
    if (bg_image->width() == cel_image->width() &&
        bg_image->height() == cel_image->height()) {
      executeAndAdd(new CopyRect(cel_image, bg_image.get(),
          gfx::Clip(0, 0, cel_image->bounds())));
    }
    else {
      ImageRef bg_image2(Image::createCopy(bg_image.get()));
      executeAndAdd(new cmd::ReplaceImage(sprite, cel->imageRef(), bg_image2));
    }
  }

  // Fill all empty cels with a flat-image filled with bgcolor
  for (frame_t frame(0); frame<sprite->totalFrames(); ++frame) {
    Cel* cel = layer->cel(frame);
    if (!cel) {
      ImageRef cel_image(Image::create(sprite->pixelFormat(),
          sprite->width(), sprite->height()));
      clear_image(cel_image.get(), bgcolor);

      // Create the new cel and add it to the new background layer
      cel = new Cel(frame, cel_image);
      executeAndAdd(new cmd::AddCel(layer, cel));
    }
  }

  executeAndAdd(new cmd::ConfigureBackground(layer));
}