Example #1
0
bool CropSpriteCommand::onEnabled(Context* context)
{
  return
    context->checkFlags(
      ContextFlags::ActiveDocumentIsWritable |
      (m_bounds.isEmpty() ? ContextFlags::HasVisibleMask: 0));
}
Example #2
0
ClearRect::ClearRect(Cel* cel, const gfx::Rect& bounds)
{
  app::Document* doc = static_cast<app::Document*>(cel->document());

  Image* image = (cel ? cel->image(): NULL);
  if (!image)
    return;

  m_offsetX = bounds.x - cel->x();
  m_offsetY = bounds.y - cel->y();

  gfx::Rect bounds2 =
    image->bounds().createIntersection(
      gfx::Rect(
        m_offsetX, m_offsetY,
        bounds.w, bounds.h));
  if (bounds.isEmpty())
    return;

  m_dstImage.reset(new WithImage(image));
  m_bgcolor = doc->bgColor(cel->layer());

  m_copy.reset(crop_image(image,
      bounds2.x, bounds2.y, bounds2.w, bounds2.h, m_bgcolor));
}
Example #3
0
void CropSpriteCommand::onExecute(Context* context)
{
  ContextWriter writer(context);
  Document* document(writer.document());
  Sprite* sprite(writer.sprite());

  gfx::Rect bounds;
  if (m_bounds.isEmpty())
    bounds = document->mask()->bounds();
  else
    bounds = m_bounds;

  {
    Transaction transaction(writer.context(), "Sprite Crop");
    document->getApi(transaction).cropSprite(sprite, bounds);
    transaction.commit();
  }
  document->generateMaskBoundaries();
  update_screen_for_document(document);
}
Example #4
0
void CropSpriteCommand::onExecute(Context* context)
{
  ContextWriter writer(context);
  Doc* document(writer.document());
  Sprite* sprite(writer.sprite());

  gfx::Rect bounds;
  if (m_bounds.isEmpty())
    bounds = document->mask()->bounds();
  else
    bounds = m_bounds;

  {
    Tx tx(writer.context(), "Sprite Crop");
    document->getApi(tx).cropSprite(sprite, bounds);
    tx.commit();
  }

#ifdef ENABLE_UI
  if (context->isUIAvailable())
    update_screen_for_document(document);
#endif
}
Example #5
0
bool shrink_bounds(Image *image, gfx::Rect& bounds, color_t refpixel)
{
  bool shrink;
  int u, v;

  bounds = image->bounds();

  // Shrink left side
  for (u=bounds.x; u<bounds.x+bounds.w; ++u) {
    shrink = true;
    for (v=bounds.y; v<bounds.y+bounds.h; ++v) {
      if (!is_same_pixel(image->pixelFormat(), image->getPixel(u, v), refpixel)) {
        shrink = false;
        break;
      }
    }
    if (!shrink)
      break;
    ++bounds.x;
    --bounds.w;
  }

  // Shrink right side
  for (u=bounds.x+bounds.w-1; u>=bounds.x; --u) {
    shrink = true;
    for (v=bounds.y; v<bounds.y+bounds.h; ++v) {
      if (!is_same_pixel(image->pixelFormat(), image->getPixel(u, v), refpixel)) {
        shrink = false;
        break;
      }
    }
    if (!shrink)
      break;
    --bounds.w;
  }

  // Shrink top side
  for (v=bounds.y; v<bounds.y+bounds.h; ++v) {
    shrink = true;
    for (u=bounds.x; u<bounds.x+bounds.w; ++u) {
      if (!is_same_pixel(image->pixelFormat(), image->getPixel(u, v), refpixel)) {
        shrink = false;
        break;
      }
    }
    if (!shrink)
      break;
    ++bounds.y;
    --bounds.h;
  }

  // Shrink bottom side
  for (v=bounds.y+bounds.h-1; v>=bounds.y; --v) {
    shrink = true;
    for (u=bounds.x; u<bounds.x+bounds.w; ++u) {
      if (!is_same_pixel(image->pixelFormat(), image->getPixel(u, v), refpixel)) {
        shrink = false;
        break;
      }
    }
    if (!shrink)
      break;
    --bounds.h;
  }

  return (!bounds.isEmpty());
}
void ExpandCelCanvas::commit(const gfx::Rect& bounds)
{
  ASSERT(!m_closed);
  ASSERT(!m_committed);

  // If the size of each image is the same, we can create an undo
  // with only the differences between both images.
  if (m_cel->getX() == m_originalCelX &&
      m_cel->getY() == m_originalCelY &&
      m_celImage->getWidth() == m_dstImage->getWidth() &&
      m_celImage->getHeight() == m_dstImage->getHeight()) {
    // Was m_celImage created in the start of the tool-loop?.
    if (m_celCreated) {
      // We can keep the m_celImage

      // We copy the destination image to the m_celImage
      copy_image(m_celImage, m_dstImage, 0, 0);

      // Add the m_celImage in the images stock of the sprite.
      m_cel->setImage(m_sprite->getStock()->addImage(m_celImage));

      // Is the undo enabled?.
      if (m_undo.isEnabled()) {
        // We can temporary remove the cel.
        static_cast<LayerImage*>(m_layer)->removeCel(m_cel);

        // We create the undo information (for the new m_celImage
        // in the stock and the new cel in the layer)...
        m_undo.pushUndoer(new undoers::AddImage(m_undo.getObjects(),
                                                m_sprite->getStock(), m_cel->getImage()));
        m_undo.pushUndoer(new undoers::AddCel(m_undo.getObjects(),
                                              m_layer, m_cel));

        // And finally we add the cel again in the layer.
        static_cast<LayerImage*>(m_layer)->addCel(m_cel);
      }
    }
    // If the m_celImage was already created before the whole process...
    else {
      // Add to the undo history the differences between m_celImage and m_dstImage
      if (m_undo.isEnabled()) {
        gfx::Rect dirtyBounds;
        if (bounds.isEmpty())
          dirtyBounds = m_celImage->getBounds();
        else
          dirtyBounds = m_celImage->getBounds().createIntersect(bounds);

        base::UniquePtr<Dirty> dirty(new Dirty(m_celImage, m_dstImage, dirtyBounds));

        dirty->saveImagePixels(m_celImage);
        if (dirty != NULL)
          m_undo.pushUndoer(new undoers::DirtyArea(m_undo.getObjects(), m_celImage, dirty));
      }

      // Copy the destination to the cel image.
      copy_image(m_celImage, m_dstImage, 0, 0);
    }
  }
  // If the size of both images are different, we have to
  // replace the entire image.
  else {
    if (m_undo.isEnabled()) {
      if (m_cel->getX() != m_originalCelX ||
          m_cel->getY() != m_originalCelY) {
        int x = m_cel->getX();
        int y = m_cel->getY();
        m_cel->setPosition(m_originalCelX, m_originalCelY);

        m_undo.pushUndoer(new undoers::SetCelPosition(m_undo.getObjects(), m_cel));

        m_cel->setPosition(x, y);
      }

      m_undo.pushUndoer(new undoers::ReplaceImage(m_undo.getObjects(),
                                                  m_sprite->getStock(), m_cel->getImage()));
    }

    // Replace the image in the stock.
    m_sprite->getStock()->replaceImage(m_cel->getImage(), m_dstImage);

    // Destroy the old cel image.
    delete m_celImage;

    // Now the m_dstImage is used, so we haven't to destroy it.
    m_dstImage = NULL;
  }

  m_committed = true;
}
Example #7
0
void ToolLoopManager::calculateDirtyArea(const gfx::Rect& strokeBounds)
{
  // Save the current dirty area if it's needed
  Region prevDirtyArea;
  if (m_toolLoop->getTracePolicy() == TracePolicy::Last)
    prevDirtyArea = m_dirtyArea;

  // Start with a fresh dirty area
  m_dirtyArea.clear();

  if (!strokeBounds.isEmpty()) {
    // Expand the dirty-area with the pen width
    Rect r1, r2;

    m_toolLoop->getPointShape()->getModifiedArea(
      m_toolLoop,
      strokeBounds.x,
      strokeBounds.y, r1);

    m_toolLoop->getPointShape()->getModifiedArea(
      m_toolLoop,
      strokeBounds.x+strokeBounds.w-1,
      strokeBounds.y+strokeBounds.h-1, r2);

    m_dirtyArea.createUnion(m_dirtyArea, Region(r1.createUnion(r2)));
  }

  // Apply offset mode
  Point offset(m_toolLoop->getOffset());
  m_dirtyArea.offset(-offset);

  // Merge new dirty area with the previous one (for tools like line
  // or rectangle it's needed to redraw the previous position and
  // the new one)
  if (m_toolLoop->getTracePolicy() == TracePolicy::Last)
    m_dirtyArea.createUnion(m_dirtyArea, prevDirtyArea);

  // Apply tiled mode
  TiledMode tiledMode = m_toolLoop->getTiledMode();
  if (tiledMode != TiledMode::NONE) {
    int w = m_toolLoop->sprite()->width();
    int h = m_toolLoop->sprite()->height();
    Region sprite_area(Rect(0, 0, w, h));
    Region outside;
    outside.createSubtraction(m_dirtyArea, sprite_area);

    switch (tiledMode) {
      case TiledMode::X_AXIS:
        outside.createIntersection(outside, Region(Rect(-w*10000, 0, w*20000, h)));
        break;
      case TiledMode::Y_AXIS:
        outside.createIntersection(outside, Region(Rect(0, -h*10000, w, h*20000)));
        break;
    }

    Rect outsideBounds = outside.bounds();
    if (outsideBounds.x < 0) outside.offset(w * (1+((-outsideBounds.x) / w)), 0);
    if (outsideBounds.y < 0) outside.offset(0, h * (1+((-outsideBounds.y) / h)));
    int x1 = outside.bounds().x;

    while (true) {
      Region in_sprite;
      in_sprite.createIntersection(outside, sprite_area);
      outside.createSubtraction(outside, in_sprite);
      m_dirtyArea.createUnion(m_dirtyArea, in_sprite);

      outsideBounds = outside.bounds();
      if (outsideBounds.isEmpty())
        break;
      else if (outsideBounds.x+outsideBounds.w > w)
        outside.offset(-w, 0);
      else if (outsideBounds.y+outsideBounds.h > h)
        outside.offset(x1-outsideBounds.x, -h);
      else
        break;
    }
  }
}