[aseprite] 105/128: Trim (or remove) cels automatically (when they are completely empty) (fix #559, fix #1111)

Tobias Hansen thansen at moszumanska.debian.org
Mon May 9 21:24:28 UTC 2016


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 5d8af3ca36b996219b72d0313134612440755acb
Author: David Capello <davidcapello at gmail.com>
Date:   Wed May 4 12:32:39 2016 -0300

    Trim (or remove) cels automatically (when they are completely empty) (fix #559, fix #1111)
---
 src/app/CMakeLists.txt                |  1 +
 src/app/cmd/trim_cel.cpp              | 89 +++++++++++++++++++++++++++++++++++
 src/app/cmd/trim_cel.h                | 47 ++++++++++++++++++
 src/app/ui/document_view.cpp          |  2 +
 src/app/ui/editor/editor.cpp          | 10 +++-
 src/app/ui/editor/pixels_movement.cpp |  5 +-
 src/app/ui/editor/standby_state.cpp   | 12 +++++
 src/app/util/clipboard.cpp            |  2 +
 src/app/util/expand_cel_canvas.cpp    |  9 ++++
 9 files changed, 175 insertions(+), 2 deletions(-)

diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index 6aecda9..1ed0b01 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -149,6 +149,7 @@ add_library(app-lib
   cmd/set_transparent_color.cpp
   cmd/set_user_data.cpp
   cmd/shift_masked_cel.cpp
+  cmd/trim_cel.cpp
   cmd/unlink_cel.cpp
   cmd/with_cel.cpp
   cmd/with_document.cpp
diff --git a/src/app/cmd/trim_cel.cpp b/src/app/cmd/trim_cel.cpp
new file mode 100644
index 0000000..5006cda
--- /dev/null
+++ b/src/app/cmd/trim_cel.cpp
@@ -0,0 +1,89 @@
+// Aseprite
+// Copyright (C) 2016  David Capello
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "app/cmd/trim_cel.h"
+
+#include "doc/algorithm/shrink_bounds.h"
+#include "doc/cel.h"
+#include "doc/primitives.h"
+
+namespace app {
+namespace cmd {
+
+using namespace doc;
+
+TrimCel::TrimCel(Cel* cel)
+  : WithCel(cel)
+  , m_originalBounds(cel->image()->bounds())
+  , m_color(cel->image()->maskColor())
+  , m_removeCel(nullptr)
+{
+  if (algorithm::shrink_bounds(cel->image(), m_bounds, m_color)) {
+    m_originalBounds.x = -m_bounds.x;
+    m_originalBounds.y = -m_bounds.y;
+  }
+  else
+    m_removeCel = new cmd::RemoveCel(cel);
+}
+
+void TrimCel::onExecute()
+{
+  if (m_removeCel)
+    m_removeCel->execute(context());
+  else
+    cropImage(m_bounds);
+}
+
+void TrimCel::onUndo()
+{
+  if (m_removeCel)
+    m_removeCel->undo();
+  else
+    cropImage(m_originalBounds);
+}
+
+void TrimCel::onRedo()
+{
+  if (m_removeCel)
+    m_removeCel->redo();
+  else
+    cropImage(m_bounds);
+}
+
+// Crops the cel image leaving the same ID in the image.
+void TrimCel::cropImage(const gfx::Rect& bounds)
+{
+  Cel* cel = this->cel();
+
+  if (bounds == cel->image()->bounds())
+    return;
+
+  ImageRef image(crop_image(cel->image(),
+                            bounds.x, bounds.y,
+                            bounds.w, bounds.h,
+                            m_color));
+
+  ObjectId id = cel->image()->id();
+  ObjectVersion ver = cel->image()->version();
+  gfx::Point newPos = cel->position() + bounds.origin();
+
+  cel->image()->setId(NullId);
+  image->setId(id);
+  image->setVersion(ver);
+  image->incrementVersion();
+
+  cel->data()->setImage(image);
+  cel->data()->setPosition(newPos);
+  cel->incrementVersion();
+}
+
+} // namespace cmd
+} // namespace app
diff --git a/src/app/cmd/trim_cel.h b/src/app/cmd/trim_cel.h
new file mode 100644
index 0000000..2304751
--- /dev/null
+++ b/src/app/cmd/trim_cel.h
@@ -0,0 +1,47 @@
+// Aseprite
+// Copyright (C) 2016  David Capello
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+
+#ifndef APP_CMD_TRIM_CEL_H_INCLUDED
+#define APP_CMD_TRIM_CEL_H_INCLUDED
+#pragma once
+
+#include "app/cmd.h"
+#include "app/cmd/remove_cel.h"
+#include "app/cmd/with_cel.h"
+#include "doc/color.h"
+#include "gfx/rect.h"
+
+namespace app {
+namespace cmd {
+
+  class TrimCel : public Cmd
+                , public WithCel {
+  public:
+    TrimCel(doc::Cel* cel);
+
+  protected:
+    void onExecute() override;
+    void onUndo() override;
+    void onRedo() override;
+    size_t onMemSize() const override {
+      return sizeof(*this) +
+        (m_removeCel ? m_removeCel->memSize() : 0);
+    }
+
+  private:
+    void cropImage(const gfx::Rect& bounds);
+
+    gfx::Rect m_bounds;
+    gfx::Rect m_originalBounds;
+    doc::color_t m_color;
+    RemoveCel* m_removeCel;
+  };
+
+} // namespace cmd
+} // namespace app
+
+#endif
diff --git a/src/app/ui/document_view.cpp b/src/app/ui/document_view.cpp
index 8926720..748d9c4 100644
--- a/src/app/ui/document_view.cpp
+++ b/src/app/ui/document_view.cpp
@@ -15,6 +15,7 @@
 #include "app/app_menus.h"
 #include "app/cmd/clear_mask.h"
 #include "app/cmd/deselect_mask.h"
+#include "app/cmd/trim_cel.h"
 #include "app/commands/commands.h"
 #include "app/console.h"
 #include "app/context_access.h"
@@ -508,6 +509,7 @@ bool DocumentView::onClear(Context* ctx)
   {
     Transaction transaction(writer.context(), "Clear");
     transaction.execute(new cmd::ClearMask(writer.cel()));
+    transaction.execute(new cmd::TrimCel(writer.cel()));
 
     if (visibleMask &&
         !Preferences::instance().selection.keepSelectionAfterClear())
diff --git a/src/app/ui/editor/editor.cpp b/src/app/ui/editor/editor.cpp
index 17d3596..da70a59 100644
--- a/src/app/ui/editor/editor.cpp
+++ b/src/app/ui/editor/editor.cpp
@@ -273,6 +273,10 @@ void Editor::setStateInternal(const EditorStatePtr& newState)
   // Notify observers
   m_observers.notifyStateChanged(this);
 
+  // Redraw layer edges
+  if (m_docPref.show.layerEdges())
+    invalidate();
+
   // Setup the new mouse cursor
   setCursor(ui::get_mouse_position());
 
@@ -682,7 +686,11 @@ void Editor::drawSpriteUnclippedRect(ui::Graphics* g, const gfx::Rect& _rc)
   }
 
   // Draw active cel edges
-  if (m_docPref.show.layerEdges()) {
+  if (m_docPref.show.layerEdges() &&
+      // Show layer edges only on "standby" like states where brush
+      // preview is shown (e.g. with this we avoid to showing the
+      // edges in states like DrawingState, etc.).
+      m_state->requireBrushPreview()) {
     Cel* cel = (m_layer ? m_layer->cel(m_frame): nullptr);
     if (cel) {
       g->drawRect(theme->colors.editorLayerEdges(),
diff --git a/src/app/ui/editor/pixels_movement.cpp b/src/app/ui/editor/pixels_movement.cpp
index 018be3b..25fab61 100644
--- a/src/app/ui/editor/pixels_movement.cpp
+++ b/src/app/ui/editor/pixels_movement.cpp
@@ -15,6 +15,7 @@
 #include "app/cmd/clear_mask.h"
 #include "app/cmd/deselect_mask.h"
 #include "app/cmd/set_mask.h"
+#include "app/cmd/trim_cel.h"
 #include "app/console.h"
 #include "app/document.h"
 #include "app/document_api.h"
@@ -176,8 +177,10 @@ void PixelsMovement::cutMask()
 {
   {
     ContextWriter writer(m_reader, 1000);
-    if (writer.cel())
+    if (writer.cel()) {
       m_transaction.execute(new cmd::ClearMask(writer.cel()));
+      m_transaction.execute(new cmd::TrimCel(writer.cel()));
+    }
   }
 
   copyMask();
diff --git a/src/app/ui/editor/standby_state.cpp b/src/app/ui/editor/standby_state.cpp
index c4e8231..66c323b 100644
--- a/src/app/ui/editor/standby_state.cpp
+++ b/src/app/ui/editor/standby_state.cpp
@@ -298,6 +298,14 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
 
   // Start the Tool-Loop
   if (layer) {
+    // Disable layer edges to avoid showing the modified cel
+    // information by ExpandCelCanvas (i.e. the cel origin is changed
+    // to 0,0 coordinate.)
+    auto& layerEdgesOption = editor->docPref().show.layerEdges;
+    bool layerEdges = layerEdgesOption();
+    if (layerEdges)
+      layerEdgesOption(false);
+
     tools::ToolLoop* toolLoop = create_tool_loop(editor, context);
     if (toolLoop) {
       EditorStatePtr newState(new DrawingState(toolLoop));
@@ -306,6 +314,10 @@ bool StandbyState::onMouseDown(Editor* editor, MouseMessage* msg)
       static_cast<DrawingState*>(newState.get())
         ->initToolLoop(editor, msg);
     }
+
+    // Restore layer edges
+    if (layerEdges)
+      layerEdgesOption(true);
     return true;
   }
 
diff --git a/src/app/util/clipboard.cpp b/src/app/util/clipboard.cpp
index c9e9746..f834baf 100644
--- a/src/app/util/clipboard.cpp
+++ b/src/app/util/clipboard.cpp
@@ -12,6 +12,7 @@
 #include "app/app.h"
 #include "app/cmd/clear_mask.h"
 #include "app/cmd/deselect_mask.h"
+#include "app/cmd/trim_cel.h"
 #include "app/console.h"
 #include "app/context_access.h"
 #include "app/document.h"
@@ -225,6 +226,7 @@ void cut(ContextWriter& writer)
     {
       Transaction transaction(writer.context(), "Cut");
       transaction.execute(new cmd::ClearMask(writer.cel()));
+      transaction.execute(new cmd::TrimCel(writer.cel()));
       transaction.execute(new cmd::DeselectMask(writer.document()));
       transaction.commit();
     }
diff --git a/src/app/util/expand_cel_canvas.cpp b/src/app/util/expand_cel_canvas.cpp
index dc2b3a3..fae9d67 100644
--- a/src/app/util/expand_cel_canvas.cpp
+++ b/src/app/util/expand_cel_canvas.cpp
@@ -16,6 +16,7 @@
 #include "app/cmd/copy_region.h"
 #include "app/cmd/replace_image.h"
 #include "app/cmd/set_cel_position.h"
+#include "app/cmd/trim_cel.h"
 #include "app/context.h"
 #include "app/document.h"
 #include "app/transaction.h"
@@ -211,6 +212,14 @@ void ExpandCelCanvas::commit()
     ASSERT(false);
   }
 
+  ASSERT(m_cel);
+  ASSERT(m_cel->layer());
+  if (m_cel &&
+      m_cel->layer() &&
+      !m_cel->layer()->isBackground()) {
+    m_transaction.execute(new cmd::TrimCel(m_cel));
+  }
+
   m_committed = true;
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list