[aseprite] 34/64: Add CopyMerged command (Ctrl+Shift+C) (fix #824)

Tobias Hansen thansen at moszumanska.debian.org
Tue Jun 21 14:43:03 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 0f3252a80befc77aed785929ae09ece749c88266
Author: David Capello <davidcapello at gmail.com>
Date:   Tue May 17 12:59:48 2016 -0300

    Add CopyMerged command (Ctrl+Shift+C) (fix #824)
---
 data/gui.xml                         |  4 ++-
 src/app/CMakeLists.txt               |  1 +
 src/app/commands/cmd_copy_merged.cpp | 51 ++++++++++++++++++++++++++
 src/app/commands/commands_list.h     |  1 +
 src/app/util/clipboard.cpp           | 18 ++++++----
 src/app/util/clipboard.h             |  2 ++
 src/app/util/new_image_from_mask.cpp | 70 ++++++++++++++++++++++++------------
 src/app/util/new_image_from_mask.h   |  6 ++--
 8 files changed, 121 insertions(+), 32 deletions(-)

diff --git a/data/gui.xml b/data/gui.xml
index 5fb3f32..8132e0e 100644
--- a/data/gui.xml
+++ b/data/gui.xml
@@ -12,7 +12,7 @@
       <key command="OpenFile" shortcut="Ctrl+O" mac="Cmd+O" />
       <key command="SaveFile" shortcut="Ctrl+S" mac="Cmd+S" />
       <key command="SaveFileAs" shortcut="Ctrl+Shift+S" mac="Cmd+Shift+S" />
-      <key command="SaveFileCopyAs" shortcut="Ctrl+Shift+C" mac="Cmd+Shift+C" />
+      <key command="SaveFileCopyAs" shortcut="Ctrl+Alt+Shift+S" mac="Cmd+Alt+Shift+S" />
       <key command="CloseFile" shortcut="Ctrl+W" mac="Cmd+W" />
       <key command="CloseAllFiles" shortcut="Ctrl+Shift+W" mac="Cmd+Shift+W" />
       <key command="ImportSpriteSheet" shortcut="Ctrl+I" mac="Cmd+I" />
@@ -35,6 +35,7 @@
       <key command="Cut" shortcut="Shift+Del" />
       <key command="Copy" shortcut="Ctrl+C" mac="Cmd+C" />
       <key command="Copy" shortcut="Ctrl+Ins" mac="Cmd+Ins" />
+      <key command="CopyMerged" shortcut="Ctrl+Shift+C" mac="Cmd+Shift+C" />
       <key command="Paste" shortcut="Ctrl+V" mac="Cmd+V" />
       <key command="Paste" shortcut="Shift+Ins" />
       <key command="Clear" shortcut="Del" />
@@ -530,6 +531,7 @@
         <separator />
         <item command="Cut" text="Cu&t" />
         <item command="Copy" text="&Copy" />
+        <item command="CopyMerged" text="Copy Mer&ged" />
         <item command="Paste" text="&Paste" />
         <item command="Clear" text="C&lear" />
         <separator />
diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index 15be8fc..58750f8 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -180,6 +180,7 @@ add_library(app-lib
   commands/cmd_color_quantization.cpp
   commands/cmd_copy.cpp
   commands/cmd_copy_cel.cpp
+  commands/cmd_copy_merged.cpp
   commands/cmd_crop.cpp
   commands/cmd_cut.cpp
   commands/cmd_deselect_mask.cpp
diff --git a/src/app/commands/cmd_copy_merged.cpp b/src/app/commands/cmd_copy_merged.cpp
new file mode 100644
index 0000000..ad4a78f
--- /dev/null
+++ b/src/app/commands/cmd_copy_merged.cpp
@@ -0,0 +1,51 @@
+// 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/commands/command.h"
+#include "app/context_access.h"
+#include "app/util/clipboard.h"
+
+namespace app {
+
+class CopyMergedCommand : public Command {
+public:
+  CopyMergedCommand();
+  Command* clone() const override { return new CopyMergedCommand(*this); }
+
+protected:
+  bool onEnabled(Context* ctx) override;
+  void onExecute(Context* ctx) override;
+};
+
+CopyMergedCommand::CopyMergedCommand()
+  : Command("CopyMerged",
+            "Copy Merged",
+            CmdUIOnlyFlag)
+{
+}
+
+bool CopyMergedCommand::onEnabled(Context* ctx)
+{
+  return ctx->checkFlags(ContextFlags::ActiveDocumentIsReadable);
+}
+
+void CopyMergedCommand::onExecute(Context* ctx)
+{
+  ContextReader reader(ctx);
+  clipboard::copy_merged(reader);
+}
+
+Command* CommandFactory::createCopyMergedCommand()
+{
+  return new CopyMergedCommand;
+}
+
+} // namespace app
diff --git a/src/app/commands/commands_list.h b/src/app/commands/commands_list.h
index 5bd933e..3447df2 100644
--- a/src/app/commands/commands_list.h
+++ b/src/app/commands/commands_list.h
@@ -25,6 +25,7 @@ FOR_EACH_COMMAND(ColorQuantization)
 FOR_EACH_COMMAND(ConvolutionMatrix)
 FOR_EACH_COMMAND(Copy)
 FOR_EACH_COMMAND(CopyCel)
+FOR_EACH_COMMAND(CopyMerged)
 FOR_EACH_COMMAND(CropSprite)
 FOR_EACH_COMMAND(Cut)
 FOR_EACH_COMMAND(DeselectMask)
diff --git a/src/app/util/clipboard.cpp b/src/app/util/clipboard.cpp
index e4b2f5a..96cb5f4 100644
--- a/src/app/util/clipboard.cpp
+++ b/src/app/util/clipboard.cpp
@@ -157,20 +157,17 @@ static void set_clipboard_image(Image* image,
   clipboard_range.invalidate();
 }
 
-static bool copy_from_document(const Site& site)
+static bool copy_from_document(const Site& site, bool merged = false)
 {
   const app::Document* document = static_cast<const app::Document*>(site.document());
+  ASSERT(document);
 
-  ASSERT(document != NULL);
-  ASSERT(document->isMaskVisible());
-
-  Image* image = new_image_from_mask(site);
+  const Mask* mask = document->mask();
+  Image* image = new_image_from_mask(site, mask, merged);
   if (!image)
     return false;
 
-  const Mask* mask = document->mask();
   const Palette* pal = document->sprite()->palette(site.frame());
-
   set_clipboard_image(
     image,
     (mask ? new Mask(*mask): nullptr),
@@ -250,6 +247,13 @@ void copy(const ContextReader& reader)
   }
 }
 
+void copy_merged(const ContextReader& reader)
+{
+  ASSERT(reader.document() != NULL);
+
+  copy_from_document(*reader.site(), true);
+}
+
 void copy_range(const ContextReader& reader, const DocumentRange& range)
 {
   ASSERT(reader.document() != NULL);
diff --git a/src/app/util/clipboard.h b/src/app/util/clipboard.h
index 755a1e6..a117bb1 100644
--- a/src/app/util/clipboard.h
+++ b/src/app/util/clipboard.h
@@ -21,6 +21,7 @@ namespace doc {
 }
 
 namespace app {
+  class Document;
   class ContextReader;
   class ContextWriter;
   class DocumentRange;
@@ -51,6 +52,7 @@ namespace app {
     void clear_content();
     void cut(ContextWriter& context);
     void copy(const ContextReader& context);
+    void copy_merged(const ContextReader& context);
     void copy_range(const ContextReader& context, const DocumentRange& range);
     void copy_image(const Image* image, const Mask* mask, const Palette* palette);
     void copy_palette(const Palette* palette, const PalettePicks& picks);
diff --git a/src/app/util/new_image_from_mask.cpp b/src/app/util/new_image_from_mask.cpp
index d54362c..a836a73 100644
--- a/src/app/util/new_image_from_mask.cpp
+++ b/src/app/util/new_image_from_mask.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-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
@@ -15,7 +15,9 @@
 #include "base/unique_ptr.h"
 #include "doc/image_impl.h"
 #include "doc/mask.h"
+#include "doc/primitives.h"
 #include "doc/site.h"
+#include "render/render.h"
 
 namespace app {
 
@@ -27,45 +29,69 @@ Image* new_image_from_mask(const Site& site)
   return new_image_from_mask(site, srcMask);
 }
 
-doc::Image* new_image_from_mask(const doc::Site& site, const doc::Mask* srcMask)
+doc::Image* new_image_from_mask(const doc::Site& site,
+                                const doc::Mask* srcMask,
+                                bool merged)
 {
   const Sprite* srcSprite = site.sprite();
-  const Image* srcMaskBitmap = srcMask->bitmap();
-  const gfx::Rect& srcBounds = srcMask->bounds();
+  const Image* srcMaskBitmap = (srcMask ? srcMask->bitmap(): nullptr);
+  gfx::Rect srcBounds = (srcMask ? srcMask->bounds(): srcSprite->bounds());
   int x, y, u, v, getx, gety;
-  const Image *src = site.image(&x, &y);
 
   ASSERT(srcSprite);
-  ASSERT(srcMask);
-  ASSERT(srcMaskBitmap);
 
   base::UniquePtr<Image> dst(Image::create(srcSprite->pixelFormat(), srcBounds.w, srcBounds.h));
   if (!dst)
     return nullptr;
 
   // Clear the new image
-  dst->setMaskColor(src ? src->maskColor(): srcSprite->transparentColor());
+  dst->setMaskColor(srcSprite->transparentColor());
   clear_image(dst, dst->maskColor());
 
-  // Copy the masked zones
-  if (src) {
-    const LockImageBits<BitmapTraits> maskBits(srcMaskBitmap, gfx::Rect(0, 0, srcBounds.w, srcBounds.h));
-    LockImageBits<BitmapTraits>::const_iterator mask_it = maskBits.begin();
+  const Image* src = nullptr;
+  if (merged) {
+    render::Render render;
+    render.renderSprite(dst, srcSprite, site.frame(),
+                        gfx::Clip(0, 0, srcBounds));
 
-    for (v=0; v<srcBounds.h; ++v) {
-      for (u=0; u<srcBounds.w; ++u, ++mask_it) {
-        ASSERT(mask_it != maskBits.end());
-
-        if (*mask_it) {
-          getx = u+srcBounds.x-x;
-          gety = v+srcBounds.y-y;
+    src = dst;
+  }
+  else {
+    src = site.image(&x, &y);
+  }
 
-          if ((getx >= 0) && (getx < src->width()) &&
-              (gety >= 0) && (gety < src->height()))
-            dst->putPixel(u, v, src->getPixel(getx, gety));
+  // Copy the masked zones
+  if (src) {
+    if (srcMaskBitmap) {
+      // Copy active layer with mask
+      const LockImageBits<BitmapTraits> maskBits(srcMaskBitmap, gfx::Rect(0, 0, srcBounds.w, srcBounds.h));
+      LockImageBits<BitmapTraits>::const_iterator mask_it = maskBits.begin();
+
+      for (v=0; v<srcBounds.h; ++v) {
+        for (u=0; u<srcBounds.w; ++u, ++mask_it) {
+          ASSERT(mask_it != maskBits.end());
+
+          if (src != dst) {
+            if (*mask_it) {
+              getx = u+srcBounds.x-x;
+              gety = v+srcBounds.y-y;
+
+              if ((getx >= 0) && (getx < src->width()) &&
+                  (gety >= 0) && (gety < src->height()))
+                dst->putPixel(u, v, src->getPixel(getx, gety));
+            }
+          }
+          else {
+            if (!*mask_it) {
+              dst->putPixel(u, v, dst->maskColor());
+            }
+          }
         }
       }
     }
+    else if (src != dst) {
+      copy_image(dst, src, -srcBounds.x, -srcBounds.y);
+    }
   }
 
   return dst.release();
diff --git a/src/app/util/new_image_from_mask.h b/src/app/util/new_image_from_mask.h
index ea8d66e..e95cfc2 100644
--- a/src/app/util/new_image_from_mask.h
+++ b/src/app/util/new_image_from_mask.h
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-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
@@ -18,7 +18,9 @@ namespace doc {
 namespace app {
 
   doc::Image* new_image_from_mask(const doc::Site& site);
-  doc::Image* new_image_from_mask(const doc::Site& site, const doc::Mask* mask);
+  doc::Image* new_image_from_mask(const doc::Site& site,
+                                  const doc::Mask* mask,
+                                  bool merged = false);
 
 } // namespace app
 

-- 
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