mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-24 09:02:31 +00:00
Added support to copy & paste to/from the Windows Clipboard.
This commit is contained in:
parent
cb6b45bb3f
commit
73d1920e78
5
NEWS.txt
5
NEWS.txt
@ -2,9 +2,10 @@
|
|||||||
NEWS
|
NEWS
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
0.7
|
0.6.2
|
||||||
---
|
-----
|
||||||
|
|
||||||
|
+ Copy & Paste use Windows clipboard (feature #2577954).
|
||||||
+ Added "Save Copy As" command (feature #2636076).
|
+ Added "Save Copy As" command (feature #2636076).
|
||||||
+ Fixed compilation support for gcc 64 bits.
|
+ Fixed compilation support for gcc 64 bits.
|
||||||
+ Fixed a bug with multiple editors and paste command.
|
+ Fixed a bug with multiple editors and paste command.
|
||||||
|
2
config.h
2
config.h
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
/* general information */
|
/* general information */
|
||||||
#define PACKAGE "ASE"
|
#define PACKAGE "ASE"
|
||||||
#define VERSION "0.6.1"
|
#define VERSION "0.6.2"
|
||||||
#define WEBSITE "http://www.aseprite.org/"
|
#define WEBSITE "http://www.aseprite.org/"
|
||||||
#define COPYRIGHT "Copyright (C) 2001-2009 David Capello"
|
#define COPYRIGHT "Copyright (C) 2001-2009 David Capello"
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ COMMON_SOURCES = \
|
|||||||
src/util/autocrop.cpp \
|
src/util/autocrop.cpp \
|
||||||
src/util/boundary.cpp \
|
src/util/boundary.cpp \
|
||||||
src/util/celmove.cpp \
|
src/util/celmove.cpp \
|
||||||
src/util/clipbrd.cpp \
|
src/util/clipboard.cpp \
|
||||||
src/util/col_file.cpp \
|
src/util/col_file.cpp \
|
||||||
src/util/filetoks.cpp \
|
src/util/filetoks.cpp \
|
||||||
src/util/functions.cpp \
|
src/util/functions.cpp \
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
|
|
||||||
dir="`pwd`"
|
dir="`pwd`"
|
||||||
version=0.6.1
|
version=0.6.2
|
||||||
distdir=ase-$version
|
distdir=ase-$version
|
||||||
|
|
||||||
freetype_files="third_party/freetype/ChangeLog \
|
freetype_files="third_party/freetype/ChangeLog \
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "raster/layer.h"
|
#include "raster/layer.h"
|
||||||
#include "raster/mask.h"
|
#include "raster/mask.h"
|
||||||
#include "raster/sprite.h"
|
#include "raster/sprite.h"
|
||||||
#include "util/clipbrd.h"
|
#include "util/clipboard.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
|
|
||||||
static bool cmd_copy_enabled(const char *argument)
|
static bool cmd_copy_enabled(const char *argument)
|
||||||
@ -43,7 +43,7 @@ static bool cmd_copy_enabled(const char *argument)
|
|||||||
|
|
||||||
static void cmd_copy_execute(const char *argument)
|
static void cmd_copy_execute(const char *argument)
|
||||||
{
|
{
|
||||||
copy_to_clipboard();
|
clipboard::copy(current_sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
Command cmd_copy = {
|
Command cmd_copy = {
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include "raster/layer.h"
|
#include "raster/layer.h"
|
||||||
#include "raster/mask.h"
|
#include "raster/mask.h"
|
||||||
#include "raster/sprite.h"
|
#include "raster/sprite.h"
|
||||||
#include "util/clipbrd.h"
|
#include "util/clipboard.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
|
|
||||||
static bool cmd_cut_enabled(const char *argument)
|
static bool cmd_cut_enabled(const char *argument)
|
||||||
@ -43,7 +43,7 @@ static bool cmd_cut_enabled(const char *argument)
|
|||||||
|
|
||||||
static void cmd_cut_execute(const char *argument)
|
static void cmd_cut_execute(const char *argument)
|
||||||
{
|
{
|
||||||
cut_to_clipboard();
|
clipboard::cut(current_sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
Command cmd_cut = {
|
Command cmd_cut = {
|
||||||
|
@ -28,13 +28,10 @@
|
|||||||
static void cmd_exit_execute(const char *argument)
|
static void cmd_exit_execute(const char *argument)
|
||||||
{
|
{
|
||||||
Sprite *sprite = get_first_sprite();
|
Sprite *sprite = get_first_sprite();
|
||||||
Sprite *clipboard = get_clipboard_sprite();
|
|
||||||
|
|
||||||
while (sprite) {
|
while (sprite) {
|
||||||
/* check if this sprite is modified */
|
// check if this sprite is modified
|
||||||
|
if (sprite_is_modified(sprite)) {
|
||||||
if (sprite_is_modified(sprite) &&
|
|
||||||
(!clipboard || sprite->id != clipboard->id)) {
|
|
||||||
if (jalert(_("Warning<<There are sprites with changes.<<Do you want quit anyway?||&Yes||&No")) != 1) {
|
if (jalert(_("Warning<<There are sprites with changes.<<Do you want quit anyway?||&Yes||&No")) != 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -22,14 +22,13 @@
|
|||||||
#include "modules/sprites.h"
|
#include "modules/sprites.h"
|
||||||
#include "raster/sprite.h"
|
#include "raster/sprite.h"
|
||||||
#include "raster/undo.h"
|
#include "raster/undo.h"
|
||||||
#include "util/clipbrd.h"
|
#include "util/clipboard.h"
|
||||||
|
|
||||||
static bool cmd_paste_enabled(const char *argument)
|
static bool cmd_paste_enabled(const char *argument)
|
||||||
{
|
{
|
||||||
Sprite *sprite = current_sprite;
|
Sprite *sprite = current_sprite;
|
||||||
Sprite *clipboard = get_clipboard_sprite();
|
|
||||||
|
|
||||||
return (sprite && clipboard && (clipboard != sprite));
|
return (sprite && clipboard::can_paste());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cmd_paste_execute(const char *argument)
|
static void cmd_paste_execute(const char *argument)
|
||||||
@ -37,7 +36,7 @@ static void cmd_paste_execute(const char *argument)
|
|||||||
if (undo_is_enabled(current_sprite->undo))
|
if (undo_is_enabled(current_sprite->undo))
|
||||||
undo_set_label(current_sprite->undo, "Paste");
|
undo_set_label(current_sprite->undo, "Paste");
|
||||||
|
|
||||||
paste_from_clipboard();
|
clipboard::paste(current_sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
Command cmd_paste = {
|
Command cmd_paste = {
|
||||||
|
@ -35,7 +35,7 @@
|
|||||||
#include "raster/blend.h"
|
#include "raster/blend.h"
|
||||||
#include "raster/image.h"
|
#include "raster/image.h"
|
||||||
#include "raster/sprite.h"
|
#include "raster/sprite.h"
|
||||||
#include "util/clipbrd.h"
|
#include "util/clipboard.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "widgets/colbar.h"
|
#include "widgets/colbar.h"
|
||||||
#include "widgets/colbut.h"
|
#include "widgets/colbut.h"
|
||||||
@ -137,8 +137,9 @@ void dialogs_draw_text()
|
|||||||
/* render text */
|
/* render text */
|
||||||
image = render_text(f, text, color);
|
image = render_text(f, text, color);
|
||||||
if (image) {
|
if (image) {
|
||||||
copy_image_to_clipboard(image);
|
clipboard::copy_image(image, sprite_get_palette(current_sprite,
|
||||||
paste_from_clipboard();
|
current_sprite->frame));
|
||||||
|
clipboard::paste(current_sprite);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
console_printf(_("Error rendering text.\n"));
|
console_printf(_("Error rendering text.\n"));
|
||||||
|
@ -420,14 +420,13 @@ static int is_sprite_in_some_editor(Sprite *sprite)
|
|||||||
*/
|
*/
|
||||||
static Sprite *get_more_reliable_sprite()
|
static Sprite *get_more_reliable_sprite()
|
||||||
{
|
{
|
||||||
Sprite *clipboard = get_clipboard_sprite();
|
|
||||||
Sprite *sprite;
|
Sprite *sprite;
|
||||||
JLink link;
|
JLink link;
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(get_sprite_list(), link) {
|
JI_LIST_FOR_EACH(get_sprite_list(), link) {
|
||||||
sprite = reinterpret_cast<Sprite*>(link->data);
|
sprite = reinterpret_cast<Sprite*>(link->data);
|
||||||
|
|
||||||
if ((sprite != clipboard) && !(is_sprite_in_some_editor(sprite)))
|
if (!(is_sprite_in_some_editor(sprite)))
|
||||||
return sprite;
|
return sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -846,6 +846,7 @@ static bool manager_msg_proc(JWidget widget, JMessage msg)
|
|||||||
/* ok, so we can execute the command represented by the
|
/* ok, so we can execute the command represented by the
|
||||||
pressed-key in the message... */
|
pressed-key in the message... */
|
||||||
if (command_is_enabled(command, NULL)) {
|
if (command_is_enabled(command, NULL)) {
|
||||||
|
// if a menu is open, close everything
|
||||||
command_execute(command, NULL);
|
command_execute(command, NULL);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
Sprite* current_sprite = NULL;
|
Sprite* current_sprite = NULL;
|
||||||
|
|
||||||
static JList sprites_list;
|
static JList sprites_list;
|
||||||
static Sprite* clipboard_sprite;
|
|
||||||
|
|
||||||
static ImageRef *images_ref_get_from_layer(Sprite* sprite, Layer *layer, int target, bool write);
|
static ImageRef *images_ref_get_from_layer(Sprite* sprite, Layer *layer, int target, bool write);
|
||||||
static void layer_get_pos(Sprite* sprite, Layer *layer, int target, bool write, int **x, int **y, int *count);
|
static void layer_get_pos(Sprite* sprite, Layer *layer, int target, bool write, int **x, int **y, int *count);
|
||||||
@ -54,7 +53,6 @@ static void layer_get_pos(Sprite* sprite, Layer *layer, int target, bool write,
|
|||||||
int init_module_sprites()
|
int init_module_sprites()
|
||||||
{
|
{
|
||||||
sprites_list = jlist_new();
|
sprites_list = jlist_new();
|
||||||
clipboard_sprite = NULL;
|
|
||||||
current_sprite = NULL;
|
current_sprite = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -63,11 +61,6 @@ void exit_module_sprites()
|
|||||||
{
|
{
|
||||||
JLink link;
|
JLink link;
|
||||||
|
|
||||||
if (clipboard_sprite) {
|
|
||||||
sprite_free(clipboard_sprite);
|
|
||||||
clipboard_sprite = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
JI_LIST_FOR_EACH(sprites_list, link) {
|
JI_LIST_FOR_EACH(sprites_list, link) {
|
||||||
sprite_free(reinterpret_cast<Sprite*>(link->data));
|
sprite_free(reinterpret_cast<Sprite*>(link->data));
|
||||||
}
|
}
|
||||||
@ -98,29 +91,6 @@ Sprite* get_next_sprite(Sprite* sprite)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprite* get_clipboard_sprite()
|
|
||||||
{
|
|
||||||
return clipboard_sprite;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_clipboard_sprite(Sprite* sprite)
|
|
||||||
{
|
|
||||||
if (clipboard_sprite) {
|
|
||||||
if (current_sprite == clipboard_sprite)
|
|
||||||
set_current_sprite(sprite);
|
|
||||||
|
|
||||||
if (is_interactive())
|
|
||||||
replace_sprite_in_editors(clipboard_sprite, sprite);
|
|
||||||
|
|
||||||
sprite_free(clipboard_sprite);
|
|
||||||
}
|
|
||||||
|
|
||||||
clipboard_sprite = sprite;
|
|
||||||
|
|
||||||
if (is_interactive())
|
|
||||||
app_realloc_sprite_list();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* adds the "sprite" in the list of sprites */
|
/* adds the "sprite" in the list of sprites */
|
||||||
void sprite_mount(Sprite* sprite)
|
void sprite_mount(Sprite* sprite)
|
||||||
{
|
{
|
||||||
@ -143,10 +113,6 @@ void sprite_unmount(Sprite* sprite)
|
|||||||
/* remove from the sprite's list */
|
/* remove from the sprite's list */
|
||||||
jlist_remove(sprites_list, sprite);
|
jlist_remove(sprites_list, sprite);
|
||||||
|
|
||||||
/* remove from the clipboard pointer */
|
|
||||||
if (sprite == get_clipboard_sprite())
|
|
||||||
clipboard_sprite = NULL;
|
|
||||||
|
|
||||||
if (is_interactive()) {
|
if (is_interactive()) {
|
||||||
/* remove this sprite from tabs */
|
/* remove this sprite from tabs */
|
||||||
tabs_remove_tab(app_get_tabsbar(), sprite);
|
tabs_remove_tab(app_get_tabsbar(), sprite);
|
||||||
|
@ -43,9 +43,6 @@ JList get_sprite_list();
|
|||||||
Sprite* get_first_sprite();
|
Sprite* get_first_sprite();
|
||||||
Sprite* get_next_sprite(Sprite* sprite);
|
Sprite* get_next_sprite(Sprite* sprite);
|
||||||
|
|
||||||
Sprite* get_clipboard_sprite();
|
|
||||||
void set_clipboard_sprite(Sprite* sprite);
|
|
||||||
|
|
||||||
void sprite_mount(Sprite* sprite);
|
void sprite_mount(Sprite* sprite);
|
||||||
void sprite_unmount(Sprite* sprite);
|
void sprite_unmount(Sprite* sprite);
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||||
*
|
*
|
||||||
* Adapted to ASE by David Capello (2003-2009)
|
* Adapted to ASE by David Capello (2003-2009)
|
||||||
* See "LICENSE.txt" for more information.
|
* See "LEGAL.txt" for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <allegro.h>
|
#include <allegro.h>
|
||||||
#include <allegro/internal/aintern.h>
|
#include <allegro/internal/aintern.h>
|
||||||
|
|
||||||
@ -35,16 +36,22 @@
|
|||||||
#include "raster/cel.h"
|
#include "raster/cel.h"
|
||||||
#include "raster/image.h"
|
#include "raster/image.h"
|
||||||
#include "raster/layer.h"
|
#include "raster/layer.h"
|
||||||
|
#include "raster/palette.h"
|
||||||
#include "raster/rotate.h"
|
#include "raster/rotate.h"
|
||||||
#include "raster/sprite.h"
|
#include "raster/sprite.h"
|
||||||
#include "raster/stock.h"
|
#include "raster/stock.h"
|
||||||
#include "raster/undoable.h"
|
#include "raster/undoable.h"
|
||||||
#include "raster/undo.h"
|
#include "raster/undo.h"
|
||||||
#include "util/clipbrd.h"
|
#include "util/clipboard.h"
|
||||||
#include "util/misc.h"
|
#include "util/misc.h"
|
||||||
#include "widgets/colbar.h"
|
#include "widgets/colbar.h"
|
||||||
#include "widgets/statebar.h"
|
#include "widgets/statebar.h"
|
||||||
|
|
||||||
|
#if defined ALLEGRO_WINDOWS
|
||||||
|
#include <winalleg.h>
|
||||||
|
#include "util/clipboard_win32.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define SCALE_MODE 0
|
#define SCALE_MODE 0
|
||||||
#define ROTATE_MODE 1
|
#define ROTATE_MODE 1
|
||||||
|
|
||||||
@ -69,11 +76,13 @@ enum {
|
|||||||
ACTION_ROTATE_BR,
|
ACTION_ROTATE_BR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool interactive_transform(JWidget widget,
|
static void destroy_clipboard(void* data);
|
||||||
Image *dest_image, Image *image,
|
static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard);
|
||||||
int x, int y,
|
static bool copy_from_sprite(Sprite* sprite);
|
||||||
int xout[4], int yout[4]);
|
static ase_uint32 get_shift_from_mask(ase_uint32 mask);
|
||||||
static int low_copy();
|
|
||||||
|
static bool interactive_transform(JWidget widget, Image *dest_image, Image *image,
|
||||||
|
int x, int y, int xout[4], int yout[4]);
|
||||||
static void apply_rotation(int x1, int y1, int x2, int y2,
|
static void apply_rotation(int x1, int y1, int x2, int y2,
|
||||||
fixed angle, int cx, int cy,
|
fixed angle, int cx, int cy,
|
||||||
int xout[4], int yout[4]);
|
int xout[4], int yout[4]);
|
||||||
@ -90,56 +99,75 @@ static void fill_in_vars(int *in_box,
|
|||||||
static void update_status_bar(JWidget editor, Image *image,
|
static void update_status_bar(JWidget editor, Image *image,
|
||||||
int x1, int y1, int x2, int y2, fixed angle);
|
int x1, int y1, int x2, int y2, fixed angle);
|
||||||
|
|
||||||
bool has_clipboard_image(int *w, int *h)
|
static bool first_time = true;
|
||||||
|
|
||||||
|
static Palette* clipboard_palette = NULL;
|
||||||
|
static Image* clipboard_image = NULL;
|
||||||
|
|
||||||
|
static void destroy_clipboard(void* data)
|
||||||
{
|
{
|
||||||
Sprite *clipboard = get_clipboard_sprite();
|
delete clipboard_palette;
|
||||||
Image *image = NULL;
|
delete clipboard_image;
|
||||||
Cel *cel;
|
|
||||||
|
|
||||||
if (clipboard) {
|
|
||||||
cel = layer_get_cel(clipboard->layer, clipboard->frame);
|
|
||||||
if (cel)
|
|
||||||
image = stock_get_image(clipboard->stock, cel->image);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image) {
|
static void set_clipboard(Image* image, Palette* palette, bool set_system_clipboard)
|
||||||
if (w) *w = image->w;
|
|
||||||
if (h) *h = image->h;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (w) *w = 0;
|
|
||||||
if (h) *h = 0;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_image_to_clipboard(Image *image)
|
|
||||||
{
|
{
|
||||||
Sprite *sprite;
|
if (first_time) {
|
||||||
Image *dest;
|
first_time = false;
|
||||||
|
app_add_hook(APP_EXIT, destroy_clipboard, NULL);
|
||||||
sprite = sprite_new_with_layer(image->imgtype, image->w, image->h);
|
|
||||||
if (sprite) {
|
|
||||||
dest = GetImage2(sprite, NULL, NULL, NULL);
|
|
||||||
image_copy(dest, image, 0, 0);
|
|
||||||
|
|
||||||
sprite_set_palette(sprite, get_current_palette(), FALSE);
|
|
||||||
|
|
||||||
set_clipboard_sprite(sprite);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cut_to_clipboard()
|
delete clipboard_palette;
|
||||||
|
delete clipboard_image;
|
||||||
|
|
||||||
|
clipboard_palette = palette;
|
||||||
|
clipboard_image = image;
|
||||||
|
|
||||||
|
// copy to the Windows clipboard
|
||||||
|
#ifdef ALLEGRO_WINDOWS
|
||||||
|
if (set_system_clipboard)
|
||||||
|
set_win32_clipboard_bitmap(image, palette);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool copy_from_sprite(Sprite* sprite)
|
||||||
{
|
{
|
||||||
if (current_sprite == NULL ||
|
assert(sprite);
|
||||||
current_sprite->layer == NULL)
|
Image* image = NewImageFromMask(sprite);
|
||||||
return;
|
if (!image)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!low_copy())
|
Palette* pal = sprite_get_palette(sprite, sprite->frame);
|
||||||
|
set_clipboard(image, pal ? palette_new_copy(pal): NULL, true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ase_uint32 get_shift_from_mask(ase_uint32 mask)
|
||||||
|
{
|
||||||
|
ase_uint32 shift = 0;
|
||||||
|
for (shift=0; shift<32; ++shift)
|
||||||
|
if (mask & (1 << shift))
|
||||||
|
return shift;
|
||||||
|
return shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool clipboard::can_paste()
|
||||||
|
{
|
||||||
|
#ifdef ALLEGRO_WINDOWS
|
||||||
|
if (win32_clipboard_contains_bitmap())
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
return clipboard_image != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clipboard::cut(Sprite* sprite)
|
||||||
|
{
|
||||||
|
assert(sprite != NULL);
|
||||||
|
assert(sprite->layer != NULL);
|
||||||
|
|
||||||
|
if (!copy_from_sprite(sprite))
|
||||||
console_printf("Can't copying an image portion from the current layer\n");
|
console_printf("Can't copying an image portion from the current layer\n");
|
||||||
else {
|
else {
|
||||||
Sprite* sprite = current_sprite;
|
|
||||||
{
|
{
|
||||||
Undoable undoable(sprite, "Cut");
|
Undoable undoable(sprite, "Cut");
|
||||||
undoable.clear_mask(app_get_color_to_clear_layer(sprite->layer));
|
undoable.clear_mask(app_get_color_to_clear_layer(sprite->layer));
|
||||||
@ -149,55 +177,63 @@ void cut_to_clipboard()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void copy_to_clipboard()
|
void clipboard::copy(Sprite* sprite)
|
||||||
{
|
{
|
||||||
if (!current_sprite)
|
assert(sprite != NULL);
|
||||||
return;
|
|
||||||
|
|
||||||
if (!low_copy())
|
if (!copy_from_sprite(sprite))
|
||||||
console_printf(_("Can't copying an image portion from the current layer\n"));
|
console_printf(_("Can't copying an image portion from the current layer\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void paste_from_clipboard()
|
void clipboard::copy_image(Image* image, Palette* pal)
|
||||||
|
{
|
||||||
|
set_clipboard(image_new_copy(image),
|
||||||
|
pal ? palette_new_copy(pal): NULL, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clipboard::paste(Sprite* sprite)
|
||||||
{
|
{
|
||||||
Sprite *clipboard = get_clipboard_sprite();
|
|
||||||
Cel *cel;
|
|
||||||
Image *image;
|
|
||||||
Image *dest_image;
|
|
||||||
int xout[4], yout[4];
|
int xout[4], yout[4];
|
||||||
int dest_x, dest_y;
|
int dst_x, dst_y;
|
||||||
|
Image *src_image;
|
||||||
|
Image* dst_image;
|
||||||
bool paste;
|
bool paste;
|
||||||
|
|
||||||
if (!current_sprite ||
|
#ifdef ALLEGRO_WINDOWS
|
||||||
current_sprite == clipboard ||
|
{
|
||||||
!clipboard->layer ||
|
Image* win32_image = NULL;
|
||||||
!is_interactive())
|
Palette* win32_palette = NULL;
|
||||||
return;
|
get_win32_clipboard_bitmap(win32_image, win32_palette);
|
||||||
|
if (win32_image != NULL)
|
||||||
if (clipboard->imgtype != current_sprite->imgtype) {
|
set_clipboard(win32_image, win32_palette, false);
|
||||||
/* TODO now the user can't select the clipboard sprite */
|
|
||||||
console_printf(_("You can't copy sprites of different image types.\nYou should select the clipboard sprite, and change the image type of it.\n"));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
cel = layer_get_cel(clipboard->layer, clipboard->frame);
|
if (clipboard_image == NULL)
|
||||||
if (!cel) {
|
|
||||||
console_printf(_("Error: No cel in the clipboard\n"));
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
image = stock_get_image(clipboard->stock, cel->image);
|
assert(sprite != NULL);
|
||||||
if (!image) {
|
|
||||||
console_printf(_("Error: No image in the clipboard\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dest_image = GetImage2(current_sprite, &dest_x, &dest_y, NULL);
|
// destination image (where to put this image)
|
||||||
if (!dest_image) {
|
dst_image = GetImage2(sprite, &dst_x, &dst_y, NULL);
|
||||||
|
if (!dst_image) {
|
||||||
console_printf(_("Error: no destination image\n"));
|
console_printf(_("Error: no destination image\n"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// source image (clipboard or a converted copy to the destination 'imgtype')
|
||||||
|
if (clipboard_image->imgtype == sprite->imgtype)
|
||||||
|
src_image = clipboard_image;
|
||||||
|
else {
|
||||||
|
src_image = image_new(sprite->imgtype,
|
||||||
|
clipboard_image->w,
|
||||||
|
clipboard_image->h);
|
||||||
|
|
||||||
|
use_current_sprite_rgb_map();
|
||||||
|
image_convert(src_image, clipboard_image);
|
||||||
|
restore_rgb_map();
|
||||||
|
}
|
||||||
|
|
||||||
|
// do the interactive-transform loop (where the user can move the floating image)
|
||||||
{
|
{
|
||||||
JWidget view = jwidget_get_view(current_editor);
|
JWidget view = jwidget_get_view(current_editor);
|
||||||
JRect vp = jview_get_viewport_position(view);
|
JRect vp = jview_get_viewport_position(view);
|
||||||
@ -205,11 +241,11 @@ void paste_from_clipboard()
|
|||||||
|
|
||||||
screen_to_editor(current_editor, vp->x1, vp->y1, &x1, &y1);
|
screen_to_editor(current_editor, vp->x1, vp->y1, &x1, &y1);
|
||||||
screen_to_editor(current_editor, vp->x2-1, vp->y2-1, &x2, &y2);
|
screen_to_editor(current_editor, vp->x2-1, vp->y2-1, &x2, &y2);
|
||||||
x = (x1+x2)/2-image->w/2;
|
x = (x1+x2)/2-src_image->w/2;
|
||||||
y = (y1+y2)/2-image->h/2;
|
y = (y1+y2)/2-src_image->h/2;
|
||||||
|
|
||||||
paste = interactive_transform(current_editor,
|
paste = interactive_transform(current_editor,
|
||||||
dest_image, image, x, y, xout, yout);
|
dst_image, src_image, x, y, xout, yout);
|
||||||
|
|
||||||
jrect_free(vp);
|
jrect_free(vp);
|
||||||
}
|
}
|
||||||
@ -219,32 +255,34 @@ void paste_from_clipboard()
|
|||||||
|
|
||||||
/* align to the destination cel-position */
|
/* align to the destination cel-position */
|
||||||
for (c=0; c<4; ++c) {
|
for (c=0; c<4; ++c) {
|
||||||
xout[c] -= dest_x;
|
xout[c] -= dst_x;
|
||||||
yout[c] -= dest_y;
|
yout[c] -= dst_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clip the box for the undo */
|
/* clip the box for the undo */
|
||||||
u1 = MAX(0, MIN(xout[0], MIN(xout[1], MIN(xout[2], xout[3]))));
|
u1 = MAX(0, MIN(xout[0], MIN(xout[1], MIN(xout[2], xout[3]))));
|
||||||
v1 = MAX(0, MIN(yout[0], MIN(yout[1], MIN(yout[2], yout[3]))));
|
v1 = MAX(0, MIN(yout[0], MIN(yout[1], MIN(yout[2], yout[3]))));
|
||||||
u2 = MIN(dest_image->w-1, MAX(xout[0], MAX(xout[1], MAX(xout[2], xout[3]))));
|
u2 = MIN(dst_image->w-1, MAX(xout[0], MAX(xout[1], MAX(xout[2], xout[3]))));
|
||||||
v2 = MIN(dest_image->h-1, MAX(yout[0], MAX(yout[1], MAX(yout[2], yout[3]))));
|
v2 = MIN(dst_image->h-1, MAX(yout[0], MAX(yout[1], MAX(yout[2], yout[3]))));
|
||||||
|
|
||||||
w = u2-u1+1;
|
w = u2-u1+1;
|
||||||
h = v2-v1+1;
|
h = v2-v1+1;
|
||||||
|
|
||||||
if (w >= 1 && h >= 1) {
|
if (w >= 1 && h >= 1) {
|
||||||
/* undo region */
|
/* undo region */
|
||||||
if (undo_is_enabled(current_sprite->undo))
|
if (undo_is_enabled(sprite->undo))
|
||||||
undo_image(current_sprite->undo, dest_image, u1, v1, w, h);
|
undo_image(sprite->undo, dst_image, u1, v1, w, h);
|
||||||
|
|
||||||
/* draw the transformed image */
|
/* draw the transformed image */
|
||||||
image_parallelogram(dest_image, image,
|
image_parallelogram(dst_image, src_image,
|
||||||
xout[0], yout[0], xout[1], yout[1],
|
xout[0], yout[0], xout[1], yout[1],
|
||||||
xout[2], yout[2], xout[3], yout[3]);
|
xout[2], yout[2], xout[3], yout[3]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update_screen_for_sprite(current_sprite);
|
if (src_image != clipboard_image)
|
||||||
|
image_free(src_image);
|
||||||
|
update_screen_for_sprite(sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************************************/
|
/**********************************************************************/
|
||||||
@ -286,6 +324,7 @@ static bool interactive_transform(JWidget widget,
|
|||||||
int done = DONE_NONE;
|
int done = DONE_NONE;
|
||||||
fixed angle = 0;
|
fixed angle = 0;
|
||||||
int cx, cy;
|
int cx, cy;
|
||||||
|
int mask_color;
|
||||||
|
|
||||||
hide_drawing_cursor(widget);
|
hide_drawing_cursor(widget);
|
||||||
|
|
||||||
@ -305,6 +344,7 @@ static bool interactive_transform(JWidget widget,
|
|||||||
|
|
||||||
/* generate the preview bitmap (for fast-blitting) */
|
/* generate the preview bitmap (for fast-blitting) */
|
||||||
preview = create_bitmap(image->w, image->h);
|
preview = create_bitmap(image->w, image->h);
|
||||||
|
mask_color = bitmap_mask_color(preview);
|
||||||
image_to_allegro(image, preview, 0, 0);
|
image_to_allegro(image, preview, 0, 0);
|
||||||
|
|
||||||
switch (image->imgtype) {
|
switch (image->imgtype) {
|
||||||
@ -313,8 +353,8 @@ static bool interactive_transform(JWidget widget,
|
|||||||
int x, y;
|
int x, y;
|
||||||
for (y=0; y<image->h; y++)
|
for (y=0; y<image->h; y++)
|
||||||
for (x=0; x<image->w; x++)
|
for (x=0; x<image->w; x++)
|
||||||
if (_rgba_geta(image_getpixel(image, x, y)) < 128)
|
if (_rgba_geta(image->method->getpixel(image, x, y)) < 128)
|
||||||
putpixel(preview, x, y, bitmap_mask_color(preview));
|
putpixel(preview, x, y, mask_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,8 +362,17 @@ static bool interactive_transform(JWidget widget,
|
|||||||
int x, y;
|
int x, y;
|
||||||
for (y=0; y<image->h; y++)
|
for (y=0; y<image->h; y++)
|
||||||
for (x=0; x<image->w; x++)
|
for (x=0; x<image->w; x++)
|
||||||
if (_graya_geta(image_getpixel(image, x, y)) < 128)
|
if (_graya_geta(image->method->getpixel(image, x, y)) < 128)
|
||||||
putpixel(preview, x, y, bitmap_mask_color(preview));
|
putpixel(preview, x, y, mask_color);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IMAGE_INDEXED: {
|
||||||
|
int x, y;
|
||||||
|
for (y=0; y<image->h; y++)
|
||||||
|
for (x=0; x<image->w; x++)
|
||||||
|
if (image->method->getpixel(image, x, y) == 0)
|
||||||
|
putpixel(preview, x, y, mask_color);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -648,40 +697,6 @@ static bool interactive_transform(JWidget widget,
|
|||||||
return done == DONE_PASTE;
|
return done == DONE_PASTE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int low_copy()
|
|
||||||
{
|
|
||||||
Sprite *sprite;
|
|
||||||
Layer *layer;
|
|
||||||
|
|
||||||
sprite = sprite_new(current_sprite->imgtype,
|
|
||||||
current_sprite->w,
|
|
||||||
current_sprite->h);
|
|
||||||
if (!sprite)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* set the current frame */
|
|
||||||
sprite_set_frame(sprite, current_sprite->frame);
|
|
||||||
|
|
||||||
/* create a new layer from the current mask (in the current
|
|
||||||
frame) */
|
|
||||||
layer = NewLayerFromMask(current_sprite, sprite);
|
|
||||||
if (!layer) {
|
|
||||||
sprite_free(sprite);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer_add_layer(sprite->set, layer);
|
|
||||||
sprite_set_layer(sprite, layer);
|
|
||||||
|
|
||||||
sprite_set_palette(sprite,
|
|
||||||
sprite_get_palette(current_sprite,
|
|
||||||
current_sprite->frame), 0);
|
|
||||||
|
|
||||||
set_clipboard_sprite(sprite);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void apply_rotation(int x1, int y1, int x2, int y2,
|
static void apply_rotation(int x1, int y1, int x2, int y2,
|
||||||
fixed angle, int cx, int cy,
|
fixed angle, int cx, int cy,
|
||||||
int xout[4], int yout[4])
|
int xout[4], int yout[4])
|
@ -23,13 +23,16 @@
|
|||||||
|
|
||||||
class Image;
|
class Image;
|
||||||
|
|
||||||
bool has_clipboard_image(int *w, int *h);
|
namespace clipboard {
|
||||||
|
|
||||||
void copy_image_to_clipboard(Image* image);
|
bool can_paste();
|
||||||
|
|
||||||
void cut_to_clipboard();
|
void cut(Sprite* sprite);
|
||||||
void copy_to_clipboard();
|
void copy(Sprite* sprite);
|
||||||
void paste_from_clipboard();
|
void copy_image(Image* image, Palette* palette);
|
||||||
|
void paste(Sprite* sprite);
|
||||||
|
|
||||||
|
} // namespace clipboard
|
||||||
|
|
||||||
#endif /* UTIL_CLIPBRD_H */
|
#endif /* UTIL_CLIPBRD_H */
|
||||||
|
|
268
src/util/clipboard_win32.h
Normal file
268
src/util/clipboard_win32.h
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2009 David Capello
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
// included by clipboard.cpp
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the Windows clipboard contains a bitmap (CF_DIB
|
||||||
|
* format).
|
||||||
|
*/
|
||||||
|
static bool win32_clipboard_contains_bitmap()
|
||||||
|
{
|
||||||
|
return IsClipboardFormatAvailable(CF_DIB);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(Image* image, Palette* palette)
|
||||||
|
{
|
||||||
|
if (!OpenClipboard(win_get_window()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!EmptyClipboard()) {
|
||||||
|
CloseClipboard();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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->imgtype) {
|
||||||
|
case IMAGE_RGB:
|
||||||
|
scanline = sizeof(ase_uint32) * image->w;
|
||||||
|
color_depth = 32;
|
||||||
|
break;
|
||||||
|
case IMAGE_GRAYSCALE:
|
||||||
|
// this is right! Grayscaled is copied as RGBA in Win32 Clipboard
|
||||||
|
scanline = sizeof(ase_uint32) * image->w;
|
||||||
|
color_depth = 32;
|
||||||
|
break;
|
||||||
|
case IMAGE_INDEXED:
|
||||||
|
padding = (4-(image->w&3))&3;
|
||||||
|
scanline = sizeof(ase_uint8) * image->w;
|
||||||
|
scanline += padding;
|
||||||
|
color_depth = 8;
|
||||||
|
palette_entries = palette->ncolors;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(scanline > 0 && color_depth > 0);
|
||||||
|
|
||||||
|
// create the BITMAPV5HEADER structure
|
||||||
|
HGLOBAL hmem = GlobalAlloc(GHND,
|
||||||
|
sizeof(BITMAPV5HEADER)
|
||||||
|
+ palette_entries*sizeof(RGBQUAD)
|
||||||
|
+ scanline*image->h);
|
||||||
|
BITMAPV5HEADER* bi = (BITMAPV5HEADER*)GlobalLock(hmem);
|
||||||
|
|
||||||
|
bi->bV5Size = sizeof(BITMAPV5HEADER);
|
||||||
|
bi->bV5Width = image->w;
|
||||||
|
bi->bV5Height = image->h;
|
||||||
|
bi->bV5Planes = 1;
|
||||||
|
bi->bV5BitCount = color_depth;
|
||||||
|
bi->bV5Compression = BI_RGB;
|
||||||
|
bi->bV5SizeImage = scanline*image->h;
|
||||||
|
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->imgtype) {
|
||||||
|
case IMAGE_RGB: {
|
||||||
|
ase_uint32* dst = (ase_uint32*)(((ase_uint8*)bi)+bi->bV5Size);
|
||||||
|
ase_uint32 c;
|
||||||
|
for (int y=image->h-1; y>=0; --y)
|
||||||
|
for (int x=0; x<image->w; ++x) {
|
||||||
|
c = image->method->getpixel(image, x, y);
|
||||||
|
*(dst++) = ((_rgba_getb(c) << 0) |
|
||||||
|
(_rgba_getg(c) << 8) |
|
||||||
|
(_rgba_getr(c) << 16) |
|
||||||
|
(_rgba_geta(c) << 24));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_GRAYSCALE: {
|
||||||
|
ase_uint32* dst = (ase_uint32*)(((ase_uint8*)bi)+bi->bV5Size);
|
||||||
|
ase_uint16 c;
|
||||||
|
for (int y=image->h-1; y>=0; --y)
|
||||||
|
for (int x=0; x<image->w; ++x) {
|
||||||
|
c = image->method->getpixel(image, x, y);
|
||||||
|
*(dst++) = ((_graya_getv(c) << 0) |
|
||||||
|
(_graya_getv(c) << 8) |
|
||||||
|
(_graya_getv(c) << 16) |
|
||||||
|
(_graya_geta(c) << 24));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IMAGE_INDEXED: {
|
||||||
|
Palette* palette = get_current_palette();
|
||||||
|
RGBQUAD* rgbquad = (RGBQUAD*)(((ase_uint8*)bi)+bi->bV5Size);
|
||||||
|
for (int i=0; i<palette->ncolors; ++i) {
|
||||||
|
rgbquad->rgbRed = _rgba_getr(palette->color[i]);
|
||||||
|
rgbquad->rgbGreen = _rgba_getg(palette->color[i]);
|
||||||
|
rgbquad->rgbBlue = _rgba_getb(palette->color[i]);
|
||||||
|
rgbquad++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ase_uint8* dst = (ase_uint8*)(((ase_uint8*)bi)+bi->bV5Size
|
||||||
|
+ palette_entries*sizeof(RGBQUAD));
|
||||||
|
for (int y=image->h-1; y>=0; --y) {
|
||||||
|
for (int x=0; x<image->w; ++x) {
|
||||||
|
*(dst++) = image->method->getpixel(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, Palette*& palette)
|
||||||
|
{
|
||||||
|
image = NULL;
|
||||||
|
palette = NULL;
|
||||||
|
|
||||||
|
if (!win32_clipboard_contains_bitmap())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!OpenClipboard(win_get_window()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
BITMAPINFO* bi = (BITMAPINFO*)GetClipboardData(CF_DIB);
|
||||||
|
if (bi && bi->bmiHeader.biCompression == BI_RGB) {
|
||||||
|
try {
|
||||||
|
image = image_new(bi->bmiHeader.biBitCount == 8 ? IMAGE_INDEXED:
|
||||||
|
IMAGE_RGB,
|
||||||
|
bi->bmiHeader.biWidth,
|
||||||
|
ABS(bi->bmiHeader.biHeight));
|
||||||
|
|
||||||
|
bool valid_image = false;
|
||||||
|
switch (bi->bmiHeader.biBitCount) {
|
||||||
|
case 32: {
|
||||||
|
// BITMAPV5HEADER* bv5 = (BITMAPV5HEADER*)GetClipboardData(CF_DIBV5);
|
||||||
|
// ase_uint32* src = (ase_uint32*)(((ase_uint8*)bv5)+bv5->bV5Size);
|
||||||
|
ase_uint32* src = (ase_uint32*)(((ase_uint8*)bi)+bi->bmiHeader.biSize);
|
||||||
|
ase_uint32 c;
|
||||||
|
// int r_shift = get_shift_from_mask(bv5->bV5RedMask);
|
||||||
|
// int g_shift = get_shift_from_mask(bv5->bV5GreenMask);
|
||||||
|
// int b_shift = get_shift_from_mask(bv5->bV5BlueMask);
|
||||||
|
// int a_shift = get_shift_from_mask(bv5->bV5AlphaMask);
|
||||||
|
|
||||||
|
for (int y=image->h-1; y>=0; --y) {
|
||||||
|
for (int x=0; x<image->w; ++x) {
|
||||||
|
c = *(src++);
|
||||||
|
// image->method->putpixel(image, x, y,
|
||||||
|
// _rgba((c & bv5->bV5RedMask) >> r_shift,
|
||||||
|
// (c & bv5->bV5GreenMask) >> g_shift,
|
||||||
|
// (c & bv5->bV5BlueMask) >> b_shift,
|
||||||
|
// (c & bv5->bV5AlphaMask) >> a_shift));
|
||||||
|
image->method->putpixel(image, x, y,
|
||||||
|
_rgba((c & 0x00ff0000) >> 16,
|
||||||
|
(c & 0x0000ff00) >> 8,
|
||||||
|
(c & 0x000000ff) >> 0,
|
||||||
|
(c & 0xff000000) >> 24));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
valid_image = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 24: {
|
||||||
|
ase_uint8* src = (((ase_uint8*)bi)+bi->bmiHeader.biSize);
|
||||||
|
ase_uint8 r, g, b;
|
||||||
|
int padding = (4-(image->w*3)&3)&3;
|
||||||
|
|
||||||
|
for (int y=image->h-1; y>=0; --y) {
|
||||||
|
for (int x=0; x<image->w; ++x) {
|
||||||
|
b = *(src++);
|
||||||
|
g = *(src++);
|
||||||
|
r = *(src++);
|
||||||
|
image->method->putpixel(image, x, y, _rgba(r, g, b, 255));
|
||||||
|
}
|
||||||
|
src += padding;
|
||||||
|
}
|
||||||
|
valid_image = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 16: {
|
||||||
|
// TODO
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8: {
|
||||||
|
int colors = bi->bmiHeader.biClrUsed > 0 ? bi->bmiHeader.biClrUsed: 256;
|
||||||
|
palette = palette_new(0, 256);
|
||||||
|
for (int c=0; c<256; ++c) {
|
||||||
|
int alpha = (c == 0) ? 0: 255;
|
||||||
|
if (c < colors) {
|
||||||
|
palette->color[c] = _rgba(bi->bmiColors[c].rgbRed,
|
||||||
|
bi->bmiColors[c].rgbGreen,
|
||||||
|
bi->bmiColors[c].rgbBlue, alpha);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
palette->color[c] = _rgba(0, 0, 0, alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ase_uint8* src = (((ase_uint8*)bi)+bi->bmiHeader.biSize+sizeof(RGBQUAD)*colors);
|
||||||
|
int padding = (4-(image->w&3))&3;
|
||||||
|
|
||||||
|
for (int y=image->h-1; y>=0; --y) {
|
||||||
|
for (int x=0; x<image->w; ++x)
|
||||||
|
image->method->putpixel(image, x, y, *(src++) & 0xff);
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
@ -174,6 +174,50 @@ Layer *NewLayerFromMask(Sprite *src_sprite, Sprite *dst_sprite)
|
|||||||
return layer;
|
return layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image* NewImageFromMask(Sprite* src_sprite)
|
||||||
|
{
|
||||||
|
ase_uint8 *address;
|
||||||
|
int x, y, u, v, getx, gety;
|
||||||
|
Image *dst, *src = GetImage2(src_sprite, &x, &y, NULL);
|
||||||
|
div_t d;
|
||||||
|
|
||||||
|
assert(src_sprite);
|
||||||
|
assert(src_sprite->mask);
|
||||||
|
assert(src_sprite->mask->bitmap);
|
||||||
|
assert(src);
|
||||||
|
|
||||||
|
dst = image_new(src_sprite->imgtype,
|
||||||
|
src_sprite->mask->w,
|
||||||
|
src_sprite->mask->h);
|
||||||
|
if (!dst)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* clear the new image */
|
||||||
|
image_clear(dst, 0);
|
||||||
|
|
||||||
|
/* copy the masked zones */
|
||||||
|
for (v=0; v<src_sprite->mask->h; v++) {
|
||||||
|
d = div(0, 8);
|
||||||
|
address = ((ase_uint8 **)src_sprite->mask->bitmap->line)[v]+d.quot;
|
||||||
|
|
||||||
|
for (u=0; u<src_sprite->mask->w; u++) {
|
||||||
|
if ((*address & (1<<d.rem))) {
|
||||||
|
getx = u+src_sprite->mask->x-x;
|
||||||
|
gety = v+src_sprite->mask->y-y;
|
||||||
|
|
||||||
|
if ((getx >= 0) && (getx < src->w) &&
|
||||||
|
(gety >= 0) && (gety < src->h))
|
||||||
|
dst->method->putpixel(dst, u, v,
|
||||||
|
src->method->getpixel(src, getx, gety));
|
||||||
|
}
|
||||||
|
|
||||||
|
_image_bitmap_next_bit(d, address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
Image *GetLayerImage(Layer *layer, int *x, int *y, int frame)
|
Image *GetLayerImage(Layer *layer, int *x, int *y, int frame)
|
||||||
{
|
{
|
||||||
Image *image = NULL;
|
Image *image = NULL;
|
||||||
|
@ -34,6 +34,7 @@ Image* GetImage2(Sprite* sprite, int *x, int *y, int *opacity);
|
|||||||
void LoadPalette(const char* filename);
|
void LoadPalette(const char* filename);
|
||||||
|
|
||||||
Layer* NewLayerFromMask(Sprite* src, Sprite* dst);
|
Layer* NewLayerFromMask(Sprite* src, Sprite* dst);
|
||||||
|
Image* NewImageFromMask(Sprite* src);
|
||||||
|
|
||||||
Image* GetLayerImage(Layer* layer, int *x, int *y, int frame);
|
Image* GetLayerImage(Layer* layer, int *x, int *y, int frame);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user