WIP: Add OSX support for Image copy/paste in the Image Editor osx-clipboard #112189

Draft
Jim-Snavely wants to merge 15 commits from Jim-Snavely/blender:osx-clipboard-111404 into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
3 changed files with 101 additions and 3 deletions
Showing only changes of commit 7c790929a9 - Show all commits

View File

@ -922,9 +922,7 @@ GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const
/* Cocoa has no support for a primary selection clipboard. */
GHOST_kCapabilityPrimaryClipboard |
/* Cocoa has no support for sampling colors from the desktop. */
GHOST_kCapabilityDesktopSample |
/* This Cocoa back-end has not yet implemented image copy/paste. */
GHOST_kCapabilityClipboardImages));
GHOST_kCapabilityDesktopSample ));
}
#pragma mark Event handlers

View File

@ -195,6 +195,27 @@ class GHOST_WindowCocoa : public GHOST_Window {
bool isDialog() const;
/**
* Returns GHOST_kSuccess if the clipboard contains an image.
*/
GHOST_TSuccess GHOST_hasClipboardImage(void);
/**
* Get image data from the Clipboard
* \param r_width: the returned image width in pixels.
* \param r_height: the returned image height in pixels.
* \return pointer uint array in RGBA byte order. Caller must free.
*/
uint *GHOST_getClipboardImage(int *r_width, int *r_height);
/**
* Put image data to the Clipboard
* \param rgba: uint array in RGBA byte order.
* \param width: the image width in pixels.
* \param height: the image height in pixels.
*/
GHOST_TSuccess GHOST_putClipboardImage(uint *rgba, int width, int height);
GHOST_TabletData &GetCocoaTabletData()
{
return m_tablet;

View File

@ -616,6 +616,85 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(uint32_t height)
return GHOST_kSuccess;
}
//returns success if we have an image in the clipboard
GHOST_TSuccess GHOST_hasClipboardImage(void) {
return GHOST_kSuccess;
// NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
// if ([[pasteboard types] containsObject:NSTIFFPboardType]) {
// return GHOST_kSuccess;
// } else {
// return GHOST_kFailure;
// }
}
//returns the image data from the clipboard if available
uint *GHOST_getClipboardImage(int *r_width, int *r_height) {
// Get the general pasteboard
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
// Check if pasteboard contains an image
if ([[pasteboard types] containsObject:NSTIFFPboardType]) {
// Get the image
NSImage* image = [[NSImage alloc] initWithPasteboard:pasteboard];
// Get image size
NSSize size = [image size];
*r_width = size.width;
*r_height = size.height;
// Create bitmap context
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, *r_width, *r_height, 8, *r_width * 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
// Draw image to context
[image drawInRect:CGRectMake(0, 0, *r_width, *r_height) fromRect:NSZeroRect operation:NSCompositingOperationCopy fraction:1.0];
// Get pixel data
uint* pixels = (uint*)CGBitmapContextGetData(context);
// Clean up
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
[image release];
return pixels;
} else {
return nil;
}
}
//takes an image and puts it in the system clipboard
GHOST_TSuccess GHOST_putClipboardImage(uint *rgba, int width, int height) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rgba, width, height, 8, width * 4, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef image = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard clearContents];
NSImage *nsImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
NSArray *copiedObjects = [NSArray arrayWithObject:nsImage];
BOOL copied = [pasteboard writeObjects:copiedObjects];
[nsImage release];
CGImageRelease(image);
if (copied) {
return GHOST_kSuccess;
} else {
return GHOST_kFailure;
}
}
GHOST_TSuccess GHOST_WindowCocoa::setClientSize(uint32_t width, uint32_t height)
{
GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid");