From cfe7c136f908f010f780bdf17b59d0e2656276c3 Mon Sep 17 00:00:00 2001 From: Damien Plisson Date: Mon, 1 Feb 2010 17:33:41 +0000 Subject: [PATCH] Cocoa/DND : added bitmap data type handling in drag'n'drop operations Conversion of OS type to ImBuf is done inside ghost. --- intern/ghost/CMakeLists.txt | 2 +- intern/ghost/SConscript | 2 +- intern/ghost/intern/GHOST_EventDragnDrop.h | 8 +- intern/ghost/intern/GHOST_SystemCocoa.mm | 122 ++++++++++++++++++++- intern/ghost/intern/GHOST_WindowCocoa.mm | 7 +- intern/ghost/intern/Makefile | 2 + 6 files changed, 134 insertions(+), 9 deletions(-) diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt index bf57da23c69..460c0858d20 100644 --- a/intern/ghost/CMakeLists.txt +++ b/intern/ghost/CMakeLists.txt @@ -24,7 +24,7 @@ # # ***** END GPL LICENSE BLOCK ***** -SET(INC . ../string ../../extern/glew/include) +SET(INC . ../string ../../extern/glew/include ../../source/blender/imbuf ../../source/blender/makesdna) FILE(GLOB SRC intern/*.cpp intern/*.mm) diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript index 6713ded0afa..d68fd44540f 100644 --- a/intern/ghost/SConscript +++ b/intern/ghost/SConscript @@ -57,7 +57,7 @@ else: if env['BF_GHOST_DEBUG']: defs.append('BF_GHOST_DEBUG') -incs = '. ../string #extern/glew/include ' + env['BF_OPENGL_INC'] +incs = '. ../string #extern/glew/include #source/blender/imbuf #source/blender/makesdna' + env['BF_OPENGL_INC'] if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'): incs = env['BF_WINTAB_INC'] + ' ' + incs env.BlenderLib ('bf_ghost', sources, Split(incs), defines=defs, libtype=['intern','player'], priority = [40,15] ) diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h index 85c18efb118..31d3545e484 100644 --- a/intern/ghost/intern/GHOST_EventDragnDrop.h +++ b/intern/ghost/intern/GHOST_EventDragnDrop.h @@ -30,6 +30,10 @@ #define _GHOST_EVENT_DRAGNDROP_H_ #include "GHOST_Event.h" +extern "C" { +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +}; /** * Drag & drop event @@ -55,7 +59,7 @@ *
Currently supported object types : *
  • UTF-8 string *
  • array of strings representing filenames (GHOST_TStringArray) - *
  • bitmap image + *
  • bitmap ImBuf */ class GHOST_EventDragnDrop : public GHOST_Event { @@ -89,7 +93,7 @@ public: switch (m_dragnDropEventData.dataType) { case GHOST_kDragnDropTypeBitmap: - //Not currently implemented + IMB_freeImBuf((ImBuf*)m_dragnDropEventData.data); break; case GHOST_kDragnDropTypeFilenames: { diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index 440425757c6..4371d4d19c8 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -1050,10 +1050,6 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType if (!data) return GHOST_kFailure; switch (draggedObjectType) { - case GHOST_kDragnDropTypeBitmap: - //TODO: implement bitmap conversion to a blender friendly format - return GHOST_kFailure; - break; case GHOST_kDragnDropTypeFilenames: droppedArray = (NSArray*)data; @@ -1102,6 +1098,124 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType eventData = (GHOST_TEventDataPtr) temp_buff; break; + + case GHOST_kDragnDropTypeBitmap: + { + NSImage *droppedImg = (NSImage*)data; + NSSize imgSize = [droppedImg size]; + ImBuf *ibuf = NULL; + GHOST_TUns8 *rasterRGB = NULL; + GHOST_TUns8 *rasterRGBA = NULL; + GHOST_TUns8 *toIBuf = NULL; + int x, y, to_i, from_i; + NSBitmapImageRep *blBitmapFormatImageRGB,*blBitmapFormatImageRGBA,*bitmapImage=nil; + NSEnumerator *enumerator; + NSImageRep *representation; + + ibuf = IMB_allocImBuf (imgSize.width , imgSize.height, 32, IB_rect, 0); + if (!ibuf) { + [droppedImg release]; + return GHOST_kFailure; + } + + /*Get the bitmap of the image*/ + enumerator = [[droppedImg representations] objectEnumerator]; + while ((representation = [enumerator nextObject])) { + if ([representation isKindOfClass:[NSBitmapImageRep class]]) { + bitmapImage = (NSBitmapImageRep *)representation; + break; + } + } + if (bitmapImage == nil) return GHOST_kFailure; + + if (([bitmapImage bitsPerPixel] == 32) && (([bitmapImage bitmapFormat] & 0x5) == 0) + && ![bitmapImage isPlanar]) { + /* Try a fast copy if the image is a meshed RGBA 32bit bitmap*/ + toIBuf = (GHOST_TUns8*)ibuf->rect; + rasterRGB = (GHOST_TUns8*)[bitmapImage bitmapData]; + for (y = 0; y < imgSize.height; y++) { + to_i = (imgSize.height-y-1)*imgSize.width; + from_i = y*imgSize.width; + memcpy(toIBuf+4*to_i, rasterRGB+4*from_i, 4*imgSize.width); + } + } + else { + /* Tell cocoa image resolution is same as current system one */ + [bitmapImage setSize:imgSize]; + + /* Convert the image in a RGBA 32bit format */ + /* As Core Graphics does not support contextes with non premutliplied alpha, + we need to get alpha key values in a separate batch */ + + /* First get RGB values w/o Alpha to avoid pre-multiplication, 32bit but last byte is unused */ + blBitmapFormatImageRGB = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:imgSize.width + pixelsHigh:imgSize.height + bitsPerSample:8 samplesPerPixel:3 hasAlpha:NO isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:(NSBitmapFormat)0 + bytesPerRow:4*imgSize.width + bitsPerPixel:32/*RGB format padded to 32bits*/]; + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGB]]; + [bitmapImage draw]; + [NSGraphicsContext restoreGraphicsState]; + + rasterRGB = (GHOST_TUns8*)[blBitmapFormatImageRGB bitmapData]; + if (rasterRGB == NULL) { + [bitmapImage release]; + [blBitmapFormatImageRGB release]; + [droppedImg release]; + return GHOST_kFailure; + } + + /* Then get Alpha values by getting the RGBA image (that is premultiplied btw) */ + blBitmapFormatImageRGBA = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL + pixelsWide:imgSize.width + pixelsHigh:imgSize.height + bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bitmapFormat:(NSBitmapFormat)0 + bytesPerRow:4*imgSize.width + bitsPerPixel:32/* RGBA */]; + + [NSGraphicsContext saveGraphicsState]; + [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:blBitmapFormatImageRGBA]]; + [bitmapImage draw]; + [NSGraphicsContext restoreGraphicsState]; + + rasterRGBA = (GHOST_TUns8*)[blBitmapFormatImageRGBA bitmapData]; + if (rasterRGBA == NULL) { + [bitmapImage release]; + [blBitmapFormatImageRGB release]; + [blBitmapFormatImageRGBA release]; + [droppedImg release]; + return GHOST_kFailure; + } + + /*Copy the image to ibuf, flipping it vertically*/ + toIBuf = (GHOST_TUns8*)ibuf->rect; + for (y = 0; y < imgSize.height; y++) { + for (x = 0; x < imgSize.width; x++) { + to_i = (imgSize.height-y-1)*imgSize.width + x; + from_i = y*imgSize.width + x; + + toIBuf[4*to_i] = rasterRGB[4*from_i]; /* R */ + toIBuf[4*to_i+1] = rasterRGB[4*from_i+1]; /* G */ + toIBuf[4*to_i+2] = rasterRGB[4*from_i+2]; /* B */ + toIBuf[4*to_i+3] = rasterRGBA[4*from_i+3]; /* A */ + } + } + + [blBitmapFormatImageRGB release]; + [blBitmapFormatImageRGBA release]; + [droppedImg release]; + } + + eventData = (GHOST_TEventDataPtr) ibuf; + } + break; default: return GHOST_kFailure; diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm index 1223f866a9b..1a8b54be0fa 100644 --- a/intern/ghost/intern/GHOST_WindowCocoa.mm +++ b/intern/ghost/intern/GHOST_WindowCocoa.mm @@ -203,11 +203,16 @@ extern "C" { { NSPoint mouseLocation = [sender draggingLocation]; NSPasteboard *draggingPBoard = [sender draggingPasteboard]; + NSImage *droppedImg; id data; switch (m_draggedObjectType) { case GHOST_kDragnDropTypeBitmap: - data = [draggingPBoard dataForType:NSTIFFPboardType]; + if([NSImage canInitWithPasteboard:draggingPBoard]) { + droppedImg = [[NSImage alloc]initWithPasteboard:draggingPBoard]; + data = droppedImg; //[draggingPBoard dataForType:NSTIFFPboardType]; + } + else return NO; break; case GHOST_kDragnDropTypeFilenames: data = [draggingPBoard propertyListForType:NSFilenamesPboardType]; diff --git a/intern/ghost/intern/Makefile b/intern/ghost/intern/Makefile index d9f2bfe7cde..23d27e61590 100644 --- a/intern/ghost/intern/Makefile +++ b/intern/ghost/intern/Makefile @@ -69,4 +69,6 @@ CPPFLAGS += -I$(NAN_STRING)/include CPPFLAGS += -I$(NAN_MEMUTIL)/include CPPFLAGS += -I.. CPPFLAGS += -I$(OPENGL_HEADERS) +CPPFLAGS += -I../../../source/blender/imbuf +CPPFLAGS += -I../../../source/blender/makesdna