[aseprite] 86/128: Use clip library to copy & paste images/custom data

Tobias Hansen thansen at moszumanska.debian.org
Mon May 9 21:24:26 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 c99a1872569fb272d1e8158d7582a76ac413ed49
Author: David Capello <davidcapello at gmail.com>
Date:   Fri Apr 29 20:42:05 2016 -0300

    Use clip library to copy & paste images/custom data
    
    With this change we finally support copy & paste images into the OS X
    pasteboard. (Fix #925, fix #533, fix #172.)
---
 src/app/CMakeLists.txt            |   1 +
 src/app/util/clipboard.cpp        |  89 ++++----
 src/app/util/clipboard_native.cpp | 296 +++++++++++++++++++++++++
 src/app/util/clipboard_native.h   |  36 ++++
 src/app/util/clipboard_win32.h    | 442 --------------------------------------
 src/clip                          |   2 +-
 6 files changed, 383 insertions(+), 483 deletions(-)

diff --git a/src/app/CMakeLists.txt b/src/app/CMakeLists.txt
index 04eea0a..6aecda9 100644
--- a/src/app/CMakeLists.txt
+++ b/src/app/CMakeLists.txt
@@ -421,6 +421,7 @@ add_library(app-lib
   ui_context.cpp
   util/autocrop.cpp
   util/clipboard.cpp
+  util/clipboard_native.cpp
   util/create_cel_copy.cpp
   util/expand_cel_canvas.cpp
   util/filetoks.cpp
diff --git a/src/app/util/clipboard.cpp b/src/app/util/clipboard.cpp
index 993cd35..c9e9746 100644
--- a/src/app/util/clipboard.cpp
+++ b/src/app/util/clipboard.cpp
@@ -28,21 +28,12 @@
 #include "app/ui/timeline.h"
 #include "app/ui_context.h"
 #include "app/util/clipboard.h"
+#include "app/util/clipboard_native.h"
 #include "app/util/new_image_from_mask.h"
 #include "base/shared_ptr.h"
 #include "doc/doc.h"
 #include "render/quantization.h"
 
-#ifdef _WIN32
-  #define USE_NATIVE_WIN32_CLIPBOARD
-#endif
-
-#ifdef USE_NATIVE_WIN32_CLIPBOARD
-  #include <windows.h>
-
-  #include "app/util/clipboard_win32.h"
-#endif
-
 #include <stdexcept>
 
 namespace app {
@@ -112,6 +103,8 @@ ClipboardManager::ClipboardManager()
   ASSERT(!g_instance);
   g_instance = this;
 
+  register_native_clipboard_formats();
+
   clipboard_range.observeUIContext();
 }
 
@@ -134,18 +127,31 @@ ClipboardManager* ClipboardManager::instance()
   return g_instance;
 }
 
-static void set_clipboard_image(Image* image, Mask* mask, Palette* palette, bool set_system_clipboard)
+static void set_clipboard_image(Image* image,
+                                Mask* mask,
+                                Palette* palette,
+                                bool set_system_clipboard,
+                                bool image_source_is_transparent)
 {
   clipboard_palette.reset(palette);
   clipboard_picks.clear();
   clipboard_image.reset(image);
   clipboard_mask.reset(mask);
 
-  // copy to the Windows clipboard
-#ifdef USE_NATIVE_WIN32_CLIPBOARD
-  if (set_system_clipboard)
-    set_win32_clipboard_bitmap(image, mask, palette);
-#endif
+  // Copy image to the native clipboard
+  if (set_system_clipboard) {
+    color_t oldMask;
+    if (image) {
+      oldMask = image->maskColor();
+      if (!image_source_is_transparent)
+        image->setMaskColor(-1);
+    }
+
+    set_native_clipboard_bitmap(image, mask, palette);
+
+    if (image && !image_source_is_transparent)
+      image->setMaskColor(oldMask);
+  }
 
   clipboard_range.invalidate();
 }
@@ -164,20 +170,22 @@ static bool copy_from_document(const Site& site)
   const Mask* mask = document->mask();
   const Palette* pal = document->sprite()->palette(site.frame());
 
-  set_clipboard_image(image,
-                      (mask ? new Mask(*mask): nullptr),
-                      (pal ? new Palette(*pal): nullptr), true);
+  set_clipboard_image(
+    image,
+    (mask ? new Mask(*mask): nullptr),
+    (pal ? new Palette(*pal): nullptr),
+    true,
+    site.layer() && !site.layer()->isBackground());
+
   return true;
 }
 
 ClipboardFormat get_current_format()
 {
-#ifdef USE_NATIVE_WIN32_CLIPBOARD
-  if (win32_clipboard_contains_bitmap())
+  // Check if the native clipboard has an image
+  if (has_native_clipboard_bitmap())
     return ClipboardImage;
-#endif
-
-  if (clipboard_image)
+  else if (clipboard_image)
     return ClipboardImage;
   else if (clipboard_range.valid())
     return ClipboardDocumentRange;
@@ -200,7 +208,7 @@ void get_document_range_info(Document** document, DocumentRange* range)
 
 void clear_content()
 {
-  set_clipboard_image(nullptr, nullptr, nullptr, true);
+  set_clipboard_image(nullptr, nullptr, nullptr, true, false);
 }
 
 void cut(ContextWriter& writer)
@@ -255,7 +263,8 @@ void copy_image(const Image* image, const Mask* mask, const Palette* pal)
   set_clipboard_image(
     Image::createCopy(image),
     (mask ? new Mask(*mask): nullptr),
-    (pal ? new Palette(*pal): nullptr), true);
+    (pal ? new Palette(*pal): nullptr),
+    true, false);
 }
 
 void copy_palette(const Palette* palette, const doc::PalettePicks& picks)
@@ -265,7 +274,8 @@ void copy_palette(const Palette* palette, const doc::PalettePicks& picks)
 
   set_clipboard_image(nullptr,
                       nullptr,
-                      new Palette(*palette), true);
+                      new Palette(*palette),
+                      true, false);
   clipboard_picks = picks;
 }
 
@@ -281,17 +291,16 @@ void paste()
   switch (get_current_format()) {
 
     case clipboard::ClipboardImage: {
-#ifdef USE_NATIVE_WIN32_CLIPBOARD
       // Get the image from the clipboard.
       {
-        Image* win32_image = NULL;
-        Mask* win32_mask = NULL;
-        Palette* win32_palette = NULL;
-        get_win32_clipboard_bitmap(win32_image, win32_mask, win32_palette);
-        if (win32_image)
-          set_clipboard_image(win32_image, win32_mask, win32_palette, false);
+        Image* native_image = nullptr;
+        Mask* native_mask = nullptr;
+        Palette* native_palette = nullptr;
+        get_native_clipboard_bitmap(&native_image, &native_mask, &native_palette);
+        if (native_image)
+          set_clipboard_image(native_image, native_mask, native_palette,
+                              false, false);
       }
-#endif
 
       if (!clipboard_image)
         return;
@@ -509,18 +518,18 @@ void paste()
 
 bool get_image_size(gfx::Size& size)
 {
-#ifdef USE_NATIVE_WIN32_CLIPBOARD
-  // Get the image from the clipboard.
-  return get_win32_clipboard_bitmap_size(size);
+#if defined(_WIN32) || defined(__APPLE__)
+  if (get_native_clipboard_bitmap_size(&size))
+    return true;
 #else
   if (clipboard_image) {
     size.w = clipboard_image->width();
     size.h = clipboard_image->height();
     return true;
   }
-  else
-    return false;
 #endif
+
+  return false;
 }
 
 Palette* get_palette()
diff --git a/src/app/util/clipboard_native.cpp b/src/app/util/clipboard_native.cpp
new file mode 100644
index 0000000..dcdf6f5
--- /dev/null
+++ b/src/app/util/clipboard_native.cpp
@@ -0,0 +1,296 @@
+// 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/util/clipboard_native.h"
+
+#include "base/serialization.h"
+#include "base/unique_ptr.h"
+#include "clip/clip.h"
+#include "doc/color_scales.h"
+#include "doc/image.h"
+#include "doc/image_impl.h"
+#include "doc/image_io.h"
+#include "doc/mask_io.h"
+#include "doc/palette_io.h"
+#include "gfx/size.h"
+#include "she/display.h"
+#include "she/system.h"
+#include "ui/alert.h"
+
+#include <sstream>
+#include <vector>
+
+namespace app {
+namespace clipboard {
+
+using namespace base::serialization;
+using namespace base::serialization::little_endian;
+
+namespace {
+  clip::format custom_image_format = 0;
+
+  void* native_display_handle() {
+    return she::instance()->defaultDisplay()->nativeHandle();
+  }
+
+  void custom_error_handler(clip::ErrorCode code) {
+    switch (code) {
+      case clip::ErrorCode::CannotLock:
+        ui::Alert::show("Error<<Cannot access to the clipboard.\nMaybe other application is using it.||&OK");
+        break;
+      case clip::ErrorCode::ImageNotSupported:
+        ui::Alert::show("Error<<The current clipboard image format is not supported.||&OK");
+        break;
+    }
+  }
+
+}
+
+void register_native_clipboard_formats()
+{
+  clip::set_error_handler(custom_error_handler);
+  custom_image_format = clip::register_format("org.aseprite.Image");
+}
+
+bool has_native_clipboard_bitmap()
+{
+  return clip::has(clip::image_format());
+}
+
+bool set_native_clipboard_bitmap(const doc::Image* image,
+                                 const doc::Mask* mask,
+                                 const doc::Palette* palette)
+{
+  clip::lock l(native_display_handle());
+  if (!l.locked())
+    return false;
+
+  l.clear();
+
+  if (!image)
+    return false;
+
+  // Set custom clipboard formats
+  if (custom_image_format) {
+    std::stringstream os;
+    write32(os,
+            (image   ? 1: 0) |
+            (mask    ? 2: 0) |
+            (palette ? 4: 0));
+    if (image) doc::write_image(os, image);
+    if (mask) doc::write_mask(os, mask);
+    if (palette) doc::write_palette(os, palette);
+
+    if (os.good()) {
+      size_t size = (size_t)os.tellp();
+      if (size > 0) {
+        std::vector<char> data(size);
+        os.seekp(0);
+        os.read(&data[0], size);
+
+        l.set_data(custom_image_format, &data[0], size);
+      }
+    }
+  }
+
+  clip::image_spec spec;
+  spec.width = image->width();
+  spec.height = image->height();
+  spec.bits_per_pixel = 32;
+  spec.bytes_per_row = (image->pixelFormat() == doc::IMAGE_RGB ?
+                        image->getRowStrideSize(): 4*spec.width);
+  spec.red_mask    = doc::rgba_r_mask;
+  spec.green_mask  = doc::rgba_g_mask;
+  spec.blue_mask   = doc::rgba_b_mask;
+  spec.alpha_mask  = doc::rgba_a_mask;
+  spec.red_shift   = doc::rgba_r_shift;
+  spec.green_shift = doc::rgba_g_shift;
+  spec.blue_shift  = doc::rgba_b_shift;
+  spec.alpha_shift = doc::rgba_a_shift;
+
+  switch (image->pixelFormat()) {
+    case doc::IMAGE_RGB: {
+      // We use the RGB image data directly
+      clip::image img(image->getPixelAddress(0, 0), spec);
+      l.set_image(img);
+      break;
+    }
+    case doc::IMAGE_GRAYSCALE: {
+      clip::image img(spec);
+      const doc::LockImageBits<doc::GrayscaleTraits> bits(image);
+      auto it = bits.begin();
+      uint32_t* dst = (uint32_t*)img.data();
+      for (int y=0; y<image->height(); ++y) {
+        for (int x=0; x<image->width(); ++x, ++it) {
+          doc::color_t c = *it;
+          *(dst++) = doc::rgba(doc::graya_getv(c),
+                               doc::graya_getv(c),
+                               doc::graya_getv(c),
+                               doc::graya_geta(c));
+        }
+      }
+      l.set_image(img);
+      break;
+    }
+    case doc::IMAGE_INDEXED: {
+      clip::image img(spec);
+      const doc::LockImageBits<doc::IndexedTraits> bits(image);
+      auto it = bits.begin();
+      uint32_t* dst = (uint32_t*)img.data();
+      for (int y=0; y<image->height(); ++y) {
+        for (int x=0; x<image->width(); ++x, ++it) {
+          doc::color_t c = palette->getEntry(*it);
+
+          // Use alpha=0 for mask color
+          if (*it == image->maskColor())
+            c &= doc::rgba_rgb_mask;
+
+          *(dst++) = c;
+        }
+      }
+      l.set_image(img);
+      break;
+    }
+  }
+
+  return true;
+}
+
+bool get_native_clipboard_bitmap(doc::Image** image,
+                                 doc::Mask** mask,
+                                 doc::Palette** palette)
+{
+  *image = nullptr;
+  *mask = nullptr;
+  *palette = nullptr;
+
+  clip::lock l(native_display_handle());
+  if (!l.locked())
+    return false;
+
+  // Prefer the custom format (to avoid losing mask and palette)
+  if (l.is_convertible(custom_image_format)) {
+    size_t size = l.get_data_length(custom_image_format);
+    if (size > 0) {
+      std::vector<char> buf(size);
+      if (l.get_data(custom_image_format, &buf[0], size)) {
+        std::stringstream is;
+        is.write(&buf[0], size);
+        is.seekp(0);
+
+        int bits = read32(is);
+        if (bits & 1) *image   = doc::read_image(is, false);
+        if (bits & 2) *mask    = doc::read_mask(is);
+        if (bits & 4) *palette = doc::read_palette(is);
+        if (image)
+          return true;
+      }
+    }
+  }
+
+  if (!l.is_convertible(clip::image_format()))
+    return false;
+
+  clip::image img;
+  if (!l.get_image(img))
+    return false;
+
+  const clip::image_spec& spec = img.spec();
+
+  base::UniquePtr<doc::Image> dst(
+    doc::Image::create(doc::IMAGE_RGB,
+                       spec.width, spec.height));
+
+  switch (spec.bits_per_pixel) {
+    case 64: {
+      doc::LockImageBits<doc::RgbTraits> bits(dst.get(), doc::Image::WriteLock);
+      auto it = bits.begin();
+      for (unsigned long y=0; y<spec.height; ++y) {
+        const uint64_t* src = (const uint64_t*)(img.data()+spec.bytes_per_row*y);
+        for (unsigned long x=0; x<spec.width; ++x, ++it, ++src) {
+          uint64_t c = *((const uint64_t*)src);
+          *it = doc::rgba(
+            uint8_t((c & spec.red_mask) >> spec.red_shift >> 8),
+            uint8_t((c & spec.green_mask) >> spec.green_shift >> 8),
+            uint8_t((c & spec.blue_mask) >> spec.blue_shift >> 8),
+            uint8_t((c & spec.alpha_mask) >> spec.alpha_shift >> 8));
+        }
+      }
+      break;
+    }
+    case 32: {
+      doc::LockImageBits<doc::RgbTraits> bits(dst.get(), doc::Image::WriteLock);
+      auto it = bits.begin();
+      for (unsigned long y=0; y<spec.height; ++y) {
+        const uint32_t* src = (const uint32_t*)(img.data()+spec.bytes_per_row*y);
+        for (unsigned long x=0; x<spec.width; ++x, ++it, ++src) {
+          const uint32_t c = *((const uint32_t*)src);
+          *it = doc::rgba(
+            uint8_t((c & spec.red_mask  ) >> spec.red_shift  ),
+            uint8_t((c & spec.green_mask) >> spec.green_shift),
+            uint8_t((c & spec.blue_mask ) >> spec.blue_shift ),
+            uint8_t((c & spec.alpha_mask) >> spec.alpha_shift));
+        }
+      }
+      break;
+    }
+    case 24: {
+      doc::LockImageBits<doc::RgbTraits> bits(dst.get(), doc::Image::WriteLock);
+      auto it = bits.begin();
+      for (unsigned long y=0; y<spec.height; ++y) {
+        const char* src = (const char*)(img.data()+spec.bytes_per_row*y);
+        for (unsigned long x=0; x<spec.width; ++x, ++it, src+=3) {
+          unsigned long c = *((const unsigned long*)src);
+          *it = doc::rgba(
+            uint8_t((c & spec.red_mask) >> spec.red_shift),
+            uint8_t((c & spec.green_mask) >> spec.green_shift),
+            uint8_t((c & spec.blue_mask) >> spec.blue_shift),
+            255);
+        }
+      }
+      break;
+    }
+    case 16: {
+      doc::LockImageBits<doc::RgbTraits> bits(dst.get(), doc::Image::WriteLock);
+      auto it = bits.begin();
+      for (unsigned long y=0; y<spec.height; ++y) {
+        const uint16_t* src = (const uint16_t*)(img.data()+spec.bytes_per_row*y);
+        for (unsigned long x=0; x<spec.width; ++x, ++it, ++src) {
+          const uint16_t c = *((const uint16_t*)src);
+          *it = doc::rgba(
+            doc::scale_5bits_to_8bits((c & spec.red_mask  ) >> spec.red_shift  ),
+            doc::scale_6bits_to_8bits((c & spec.green_mask) >> spec.green_shift),
+            doc::scale_5bits_to_8bits((c & spec.blue_mask ) >> spec.blue_shift ),
+            255);
+        }
+      }
+      break;
+    }
+  }
+
+  *image = dst.release();
+  return true;
+}
+
+bool get_native_clipboard_bitmap_size(gfx::Size* size)
+{
+  clip::image_spec spec;
+  if (clip::get_image_spec(spec)) {
+    size->w = spec.width;
+    size->h = spec.height;
+    return true;
+  }
+  else
+    return false;
+}
+
+} // namespace clipboard
+} // namespace app
diff --git a/src/app/util/clipboard_native.h b/src/app/util/clipboard_native.h
new file mode 100644
index 0000000..f4eabef
--- /dev/null
+++ b/src/app/util/clipboard_native.h
@@ -0,0 +1,36 @@
+// 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_UTIL_CLIPBOARD_NATIVE_H_INCLUDED
+#define APP_UTIL_CLIPBOARD_NATIVE_H_INCLUDED
+#pragma once
+
+#include "gfx/fwd.h"
+
+namespace doc {
+  class Image;
+  class Mask;
+  class Palette;
+}
+
+namespace app {
+namespace clipboard {
+
+void register_native_clipboard_formats();
+bool has_native_clipboard_bitmap();
+bool set_native_clipboard_bitmap(const doc::Image* image,
+                                 const doc::Mask* mask,
+                                 const doc::Palette* palette);
+bool get_native_clipboard_bitmap(doc::Image** image,
+                                 doc::Mask** mask,
+                                 doc::Palette** palette);
+bool get_native_clipboard_bitmap_size(gfx::Size* size);
+
+} // namespace clipboard
+} // namespace app
+
+#endif
diff --git a/src/app/util/clipboard_win32.h b/src/app/util/clipboard_win32.h
deleted file mode 100644
index 5d007c5..0000000
--- a/src/app/util/clipboard_win32.h
+++ /dev/null
@@ -1,442 +0,0 @@
-// Aseprite
-// 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
-// published by the Free Software Foundation.
-
-// included by clipboard.cpp
-
-#include "base/serialization.h"
-#include "doc/color_scales.h"
-#include "doc/image_io.h"
-#include "doc/mask_io.h"
-#include "doc/palette_io.h"
-#include "she/display.h"
-#include "she/system.h"
-#include "ui/alert.h"
-
-#ifndef LCS_WINDOWS_COLOR_SPACE
-#define LCS_WINDOWS_COLOR_SPACE 'Win '
-#endif
-
-#ifndef CF_DIBV5
-#define CF_DIBV5            17
-#endif
-
-namespace {
-
-using namespace doc;
-using namespace base::serialization;
-using namespace base::serialization::little_endian;
-
-static UINT custom_clipboard_format = 0;
-
-static uint32_t get_shift_from_mask(uint32_t mask)
-{
-  uint32_t shift = 0;
-  for (shift=0; shift<32; ++shift)
-    if (mask & (1 << shift))
-      return shift;
-  return shift;
-}
-
-bool win32_open_clipboard(HWND hwnd)
-{
-  if (!custom_clipboard_format) {
-    custom_clipboard_format = RegisterClipboardFormat(L"Aseprite.Image.1");
-    if (!custom_clipboard_format)
-      LOG("Error registering custom clipboard format: %d\n", GetLastError());
-  }
-
-  for (int i=0; i<5; ++i) {
-    if (OpenClipboard(hwnd))
-      return true;
-
-    Sleep(100);
-  }
-  return false;
-}
-
-/**
- * Returns true if the Windows clipboard contains a bitmap (CF_DIB
- * format).
- */
-static bool win32_clipboard_contains_bitmap()
-{
-  return IsClipboardFormatAvailable(CF_DIB) ? true: false;
-}
-
-/**
- * Changes the Windows clipboard content to the specified image. The
- * palette is optional and only used if the image is IMAGE_INDEXED type.
- */
-static void set_win32_clipboard_bitmap(const Image* image, const Mask* mask, Palette* palette)
-{
-  HWND hwnd = static_cast<HWND>(she::instance()->defaultDisplay()->nativeHandle());
-  if (!win32_open_clipboard(hwnd))
-    return;
-
-  if (!EmptyClipboard()) {
-    CloseClipboard();
-    return;
-  }
-
-  if (!image) {
-    CloseClipboard();
-    return;
-  }
-
-  // Set custom clipboard formats
-  if (custom_clipboard_format) {
-    std::stringstream os;
-    write32(os,
-            (image   ? 1: 0) |
-            (mask    ? 2: 0) |
-            (palette ? 4: 0));
-    if (image) doc::write_image(os, image);
-    if (mask) doc::write_mask(os, mask);
-    if (palette) doc::write_palette(os, palette);
-
-    if (os.good()) {
-      size_t size = (size_t)os.tellp();
-      HGLOBAL hmem = GlobalAlloc(GHND, size+4);
-      if (hmem) {
-        char* p = (char*)GlobalLock(hmem);
-        if (p) {
-          *((uint32_t*)p) = size;
-          os.seekp(0);
-          os.read(p+4, size);
-        }
-        GlobalUnlock(hmem);
-        if (p)
-          SetClipboardData(custom_clipboard_format, hmem);
-        GlobalFree(hmem);
-      }
-    }
-  }
-
-  // information to create the memory necessary for the bitmap
-  int padding = 0;
-  int scanline = 0;
-  int color_depth = 0;
-  int palette_entries = 0;
-
-  switch (image->pixelFormat()) {
-    case IMAGE_RGB:
-      scanline = sizeof(uint32_t) * image->width();
-      color_depth = 32;
-      break;
-    case IMAGE_GRAYSCALE:
-       // this is right! Grayscaled is copied as RGBA in Win32 Clipboard
-      scanline = sizeof(uint32_t) * image->width();
-      color_depth = 32;
-      break;
-    case IMAGE_INDEXED:
-      ASSERT(palette);
-      padding = (4-(image->width()&3))&3;
-      scanline = sizeof(uint8_t) * image->width();
-      scanline += padding;
-      color_depth = 8;
-      palette_entries = palette->size();
-      break;
-  }
-  ASSERT(scanline > 0 && color_depth > 0);
-
-  // create the BITMAPV5HEADER structure
-  HGLOBAL hmem = GlobalAlloc(GHND,
-                             sizeof(BITMAPV5HEADER)
-                             + palette_entries*sizeof(RGBQUAD)
-                             + scanline*image->height());
-  if (!hmem) {
-    // TODO cannot copy exception
-    CloseClipboard();
-    return;
-  }
-
-  BITMAPV5HEADER* bi = (BITMAPV5HEADER*)GlobalLock(hmem);
-
-  bi->bV5Size = sizeof(BITMAPV5HEADER);
-  bi->bV5Width = image->width();
-  bi->bV5Height = image->height();
-  bi->bV5Planes = 1;
-  bi->bV5BitCount = color_depth;
-  bi->bV5Compression = BI_RGB;
-  bi->bV5SizeImage = scanline*image->height();
-  bi->bV5RedMask   = 0x00ff0000;
-  bi->bV5GreenMask = 0x0000ff00;
-  bi->bV5BlueMask  = 0x000000ff;
-  bi->bV5AlphaMask = 0xff000000;
-  bi->bV5CSType = LCS_WINDOWS_COLOR_SPACE;
-  bi->bV5Intent = LCS_GM_GRAPHICS;
-  bi->bV5ClrUsed = palette_entries == 256 ? 0: palette_entries;
-
-  // write pixels
-  switch (image->pixelFormat()) {
-    case IMAGE_RGB: {
-      uint32_t* dst = (uint32_t*)(((uint8_t*)bi)+bi->bV5Size);
-      uint32_t c;
-      for (int y=image->height()-1; y>=0; --y)
-        for (int x=0; x<image->width(); ++x) {
-          c = get_pixel_fast<RgbTraits>(image, x, y);
-          *(dst++) = ((rgba_getb(c) <<  0) |
-                      (rgba_getg(c) <<  8) |
-                      (rgba_getr(c) << 16) |
-                      (rgba_geta(c) << 24));
-        }
-      break;
-    }
-    case IMAGE_GRAYSCALE: {
-      uint32_t* dst = (uint32_t*)(((uint8_t*)bi)+bi->bV5Size);
-      uint16_t c;
-      for (int y=image->height()-1; y>=0; --y)
-        for (int x=0; x<image->width(); ++x) {
-          c = get_pixel_fast<GrayscaleTraits>(image, x, y);
-          *(dst++) = ((graya_getv(c) <<  0) |
-                      (graya_getv(c) <<  8) |
-                      (graya_getv(c) << 16) |
-                      (graya_geta(c) << 24));
-        }
-      break;
-    }
-    case IMAGE_INDEXED: {
-      ASSERT(palette);
-      RGBQUAD* rgbquad = (RGBQUAD*)(((uint8_t*)bi)+bi->bV5Size);
-      for (int i=0; i<palette->size(); ++i) {
-        rgbquad->rgbRed   = rgba_getr(palette->getEntry(i));
-        rgbquad->rgbGreen = rgba_getg(palette->getEntry(i));
-        rgbquad->rgbBlue  = rgba_getb(palette->getEntry(i));
-        rgbquad++;
-      }
-
-      uint8_t* dst = (uint8_t*)(((uint8_t*)bi)+bi->bV5Size
-                                    + palette_entries*sizeof(RGBQUAD));
-      for (int y=image->height()-1; y>=0; --y) {
-        for (int x=0; x<image->width(); ++x) {
-          *(dst++) = get_pixel_fast<IndexedTraits>(image, x, y);
-        }
-        dst += padding;
-      }
-      break;
-    }
-  }
-
-  GlobalUnlock(hmem);
-  SetClipboardData(CF_DIBV5, hmem);
-  CloseClipboard();
-
-  GlobalFree(hmem);
-}
-
-/**
- * Creates an Image from the current Windows Clipboard content.
- */
-static void get_win32_clipboard_bitmap(Image*& image, Mask*& mask, Palette*& palette)
-{
-  image = nullptr;
-  mask = nullptr;
-  palette = nullptr;
-
-  if (!win32_clipboard_contains_bitmap())
-    return;
-
-  HWND hwnd = static_cast<HWND>(she::instance()->defaultDisplay()->nativeHandle());
-  if (!win32_open_clipboard(hwnd))
-    return;
-
-  // Prefer the custom format (to avoid losing data)
-  if (custom_clipboard_format &&
-      IsClipboardFormatAvailable(custom_clipboard_format)) {
-    const char* ptr = (const char*)GetClipboardData(custom_clipboard_format);
-    if (ptr) {
-      size_t size = *((uint32_t*)ptr);
-      if (size > 0) {
-        std::stringstream is;
-        is.write(ptr+4, size);
-
-        int bits = read32(is);
-        if (bits & 1) image   = doc::read_image(is, false);
-        if (bits & 2) mask    = doc::read_mask(is);
-        if (bits & 4) palette = doc::read_palette(is);
-      }
-
-      CloseClipboard();
-      if (image)
-        return;
-    }
-  }
-
-  BITMAPINFO* bi = (BITMAPINFO*)GetClipboardData(CF_DIB);
-  if (bi) {
-    if (bi->bmiHeader.biCompression != BI_RGB &&
-        bi->bmiHeader.biCompression != BI_BITFIELDS) {
-      ui::Alert::show("Error<<The current Windows clipboard format is not a bitmap.||&OK");
-      return;
-    }
-
-    try {
-      image = Image::create(bi->bmiHeader.biBitCount == 8 ? IMAGE_INDEXED:
-                                                            IMAGE_RGB,
-                            bi->bmiHeader.biWidth,
-                            ABS(bi->bmiHeader.biHeight));
-
-      bool valid_image = false;
-      switch (bi->bmiHeader.biBitCount) {
-
-        // 32 BPP
-        case 32:
-          if (bi->bmiHeader.biCompression == BI_BITFIELDS) {
-            uint32_t* src = (uint32_t*)(((uint8_t*)bi)+bi->bmiHeader.biSize+sizeof(RGBQUAD)*3);
-            uint32_t c;
-
-            uint32_t r_mask = (uint32_t)*((uint32_t*)&bi->bmiColors[0]);
-            uint32_t g_mask = (uint32_t)*((uint32_t*)&bi->bmiColors[1]);
-            uint32_t b_mask = (uint32_t)*((uint32_t*)&bi->bmiColors[2]);
-            uint32_t r_shift = get_shift_from_mask(r_mask);
-            uint32_t g_shift = get_shift_from_mask(g_mask);
-            uint32_t b_shift = get_shift_from_mask(b_mask);
-
-            for (int y=image->height()-1; y>=0; --y) {
-              uint32_t* dst = (uint32_t*)image->getPixelAddress(0, y);
-
-              for (int x=0; x<image->width(); ++x) {
-                c = *(src++);
-                *(dst++) = rgba((c & r_mask) >> r_shift,
-                                (c & g_mask) >> g_shift,
-                                (c & b_mask) >> b_shift, 255);
-              }
-            }
-          }
-          else if (bi->bmiHeader.biCompression == BI_RGB) {
-            uint32_t* src = (uint32_t*)(((uint8_t*)bi)+bi->bmiHeader.biSize);
-            uint32_t c;
-
-            for (int y=image->height()-1; y>=0; --y) {
-              uint32_t* dst = (uint32_t*)image->getPixelAddress(0, y);
-
-              for (int x=0; x<image->width(); ++x) {
-                c = *(src++);
-                *(dst++) = rgba((c & 0x00ff0000) >> 16,
-                                (c & 0x0000ff00) >> 8,
-                                (c & 0x000000ff) >> 0,
-                                (c & 0xff000000) >> 24);
-              }
-            }
-          }
-          valid_image = true;
-          break;
-
-        // 24 BPP
-        case 24: {
-          uint8_t* src = (((uint8_t*)bi)+bi->bmiHeader.biSize);
-          uint8_t r, g, b;
-          int padding = (4-((image->width()*3)&3))&3;
-
-          for (int y=image->height()-1; y>=0; --y) {
-            uint32_t* dst = (uint32_t*)image->getPixelAddress(0, y);
-
-            for (int x=0; x<image->width(); ++x) {
-              b = *(src++);
-              g = *(src++);
-              r = *(src++);
-              *(dst++) = rgba(r, g, b, 255);
-            }
-            src += padding;
-          }
-          valid_image = true;
-          break;
-        }
-
-        // 16 BPP
-        case 16: {
-          uint16_t* src = (uint16_t*)(((uint8_t*)bi)+bi->bmiHeader.biSize+sizeof(RGBQUAD)*3);
-          uint16_t word;
-          uint8_t r, g, b;
-          int padding = ((4-((image->width()*2)&3))&3)/2;
-
-          uint32_t r_mask = (uint32_t)*((uint32_t*)&bi->bmiColors[0]);
-          uint32_t g_mask = (uint32_t)*((uint32_t*)&bi->bmiColors[1]);
-          uint32_t b_mask = (uint32_t)*((uint32_t*)&bi->bmiColors[2]);
-          uint32_t r_shift = get_shift_from_mask(r_mask);
-          uint32_t g_shift = get_shift_from_mask(g_mask);
-          uint32_t b_shift = get_shift_from_mask(b_mask);
-
-          for (int y=image->height()-1; y>=0; --y) {
-            for (int x=0; x<image->width(); ++x) {
-              word = *(src++);
-              r = scale_5bits_to_8bits((word & r_mask) >> r_shift);
-              g = scale_6bits_to_8bits((word & g_mask) >> g_shift);
-              b = scale_5bits_to_8bits((word & b_mask) >> b_shift);
-              put_pixel_fast<RgbTraits>(image, x, y, rgba(r, g, b, 255));
-            }
-            src += padding;
-          }
-          valid_image = true;
-          break;
-        }
-
-        // 8 BPP
-        case 8: {
-          int colors = bi->bmiHeader.biClrUsed > 0 ? bi->bmiHeader.biClrUsed: 256;
-          palette = new Palette(frame_t(0), colors);
-          for (int c=0; c<colors; ++c) {
-            palette->setEntry(c, rgba(bi->bmiColors[c].rgbRed,
-                                       bi->bmiColors[c].rgbGreen,
-                                       bi->bmiColors[c].rgbBlue, 255));
-          }
-
-          uint8_t* src = (((uint8_t*)bi)+bi->bmiHeader.biSize+sizeof(RGBQUAD)*colors);
-          int padding = (4-(image->width()&3))&3;
-
-          for (int y=image->height()-1; y>=0; --y) {
-            for (int x=0; x<image->width(); ++x) {
-              int c = *(src++);
-              put_pixel_fast<IndexedTraits>(image, x, y, MID(0, c, colors-1));
-            }
-
-            src += padding;
-          }
-
-          valid_image = true;
-          break;
-        }
-
-      }
-
-      if (!valid_image) {
-        delete image;
-        delete palette;
-        image = NULL;
-        palette = NULL;
-      }
-    }
-    catch (...) {
-      delete image;
-      delete palette;
-      image = NULL;
-      palette = NULL;
-    }
-  }
-
-  CloseClipboard();
-}
-
-static bool get_win32_clipboard_bitmap_size(gfx::Size& size)
-{
-  bool result = false;
-
-  HWND hwnd = static_cast<HWND>(she::instance()->defaultDisplay()->nativeHandle());
-
-  if (win32_clipboard_contains_bitmap() && win32_open_clipboard(hwnd)) {
-    BITMAPINFO* bi = (BITMAPINFO*)GetClipboardData(CF_DIB);
-    if (bi) {
-      size.w = bi->bmiHeader.biWidth;
-      size.h = ABS(bi->bmiHeader.biHeight);
-      result = true;
-    }
-    CloseClipboard();
-  }
-  return result;
-}
-
-}
diff --git a/src/clip b/src/clip
index e57130a..5ef7852 160000
--- a/src/clip
+++ b/src/clip
@@ -1 +1 @@
-Subproject commit e57130a56659d001d7bc33081c7cb3abe0621be2
+Subproject commit 5ef7852ae4d297aa5ab14ad5e5728e1f0c2e50bd

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