mirror of
https://github.com/fltk/fltk.git
synced 2026-05-27 19:10:24 +08:00
Make Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle() return a depth-4 image
This change allows to capture the rounded corners of a top-level GL window. Also, rename Fl_Cocoa_Window_Driver::capture_decorated_window_10_5() from capture_decorated_window_10_6() because this function uses CGWindowListCreateImageFromArray() available from macOS 10.5.
This commit is contained in:
+19
-13
@@ -4542,14 +4542,17 @@ static NSBitmapImageRep* GL_rect_to_nsbitmap(Fl_Window *win, int x, int y, int w
|
|||||||
if (!plugin) return nil;
|
if (!plugin) return nil;
|
||||||
Fl_RGB_Image *img = plugin->rectangle_capture(win, x, y, w, h);
|
Fl_RGB_Image *img = plugin->rectangle_capture(win, x, y, w, h);
|
||||||
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:img->w() pixelsHigh:img->h() bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:4*img->w() bitsPerPixel:32];
|
NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:img->w() pixelsHigh:img->h() bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:4*img->w() bitsPerPixel:32];
|
||||||
memset([bitmap bitmapData], 0xFF, [bitmap bytesPerPlane]);
|
if (img->d() == 4) memcpy([bitmap bitmapData], img->array, 4*img->data_w()*img->data_h());
|
||||||
const uchar *from = img->array;
|
else {
|
||||||
for (int r = 0; r < img->h(); r++) {
|
memset([bitmap bitmapData], 0xFF, [bitmap bytesPerPlane]);
|
||||||
uchar *to = [bitmap bitmapData] + r * [bitmap bytesPerRow];
|
const uchar *from = img->array;
|
||||||
for (int c = 0; c < img->w(); c++) {
|
for (int r = 0; r < img->h(); r++) {
|
||||||
memcpy(to, from, 3);
|
uchar *to = [bitmap bitmapData] + r * [bitmap bytesPerRow];
|
||||||
from += 3;
|
for (int c = 0; c < img->w(); c++) {
|
||||||
to += 4;
|
memcpy(to, from, 3);
|
||||||
|
from += 3;
|
||||||
|
to += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete img;
|
delete img;
|
||||||
@@ -4800,8 +4803,8 @@ static CGImageRef capture_decorated_window_SCK(NSWindow *nswin) {
|
|||||||
#endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
|
#endif //MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
|
||||||
|
|
||||||
|
|
||||||
CGImageRef Fl_Cocoa_Window_Driver::capture_decorated_window_10_6(NSWindow *nswin) {
|
CGImageRef Fl_Cocoa_Window_Driver::capture_decorated_window_10_5(NSWindow *nswin) {
|
||||||
// usable with 10.6 and above
|
// usable with 10.5 and above
|
||||||
CGImageRef img = NULL;
|
CGImageRef img = NULL;
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||||
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
|
# if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_VERSION_15_0
|
||||||
@@ -4824,15 +4827,18 @@ CGImageRef Fl_Cocoa_Window_Driver::capture_decorated_window_10_6(NSWindow *nswin
|
|||||||
|
|
||||||
static CGImageRef capture_window_titlebar(Fl_Window *win, Fl_Cocoa_Window_Driver *cocoa_dr) {
|
static CGImageRef capture_window_titlebar(Fl_Window *win, Fl_Cocoa_Window_Driver *cocoa_dr) {
|
||||||
CGImageRef img;
|
CGImageRef img;
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
|
||||||
if (fl_mac_os_version >= 100600) { // verified OK from 10.6
|
if (fl_mac_os_version >= 100600) { // verified OK from 10.6
|
||||||
FLWindow *nswin = fl_xid(win);
|
FLWindow *nswin = fl_xid(win);
|
||||||
CGImageRef img_full = Fl_Cocoa_Window_Driver::capture_decorated_window_10_6(nswin);
|
CGImageRef img_full = Fl_Cocoa_Window_Driver::capture_decorated_window_10_5(nswin);
|
||||||
int bt = [nswin frame].size.height - [[nswin contentView] frame].size.height;
|
int bt = [nswin frame].size.height - [[nswin contentView] frame].size.height;
|
||||||
int s = CGImageGetWidth(img_full) / [nswin frame].size.width;
|
int s = CGImageGetWidth(img_full) / [nswin frame].size.width;
|
||||||
CGRect cgr = CGRectMake(0, 0, CGImageGetWidth(img_full), bt * s);
|
CGRect cgr = CGRectMake(0, 0, CGImageGetWidth(img_full), bt * s);
|
||||||
img = CGImageCreateWithImageInRect(img_full, cgr);
|
img = CGImageCreateWithImageInRect(img_full, cgr); // 10.4
|
||||||
CGImageRelease(img_full);
|
CGImageRelease(img_full);
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
int w = win->w(), h = win->decorated_h() - win->h();
|
int w = win->w(), h = win->decorated_h() - win->h();
|
||||||
Fl_Graphics_Driver::default_driver().scale(1);
|
Fl_Graphics_Driver::default_driver().scale(1);
|
||||||
img = cocoa_dr->CGImage_from_window_rect(0, -h, w, h, false);
|
img = cocoa_dr->CGImage_from_window_rect(0, -h, w, h, false);
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ static uchar *convert_BGRA_to_RGB(uchar *baseAddress, int w, int h, int mByteWid
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static Fl_RGB_Image *cgimage_to_rgb3(CGImageRef img) {
|
static Fl_RGB_Image *cgimage_to_rgb4(CGImageRef img) {
|
||||||
int w = (int)CGImageGetWidth(img);
|
int w = (int)CGImageGetWidth(img);
|
||||||
int h = (int)CGImageGetHeight(img);
|
int h = (int)CGImageGetHeight(img);
|
||||||
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
|
CGColorSpaceRef cspace = CGColorSpaceCreateDeviceRGB();
|
||||||
@@ -463,15 +463,7 @@ static Fl_RGB_Image *cgimage_to_rgb3(CGImageRef img) {
|
|||||||
CGColorSpaceRelease(cspace);
|
CGColorSpaceRelease(cspace);
|
||||||
CGContextDrawImage(auxgc, CGRectMake(0, 0, w, h), img);
|
CGContextDrawImage(auxgc, CGRectMake(0, 0, w, h), img);
|
||||||
CGContextRelease(auxgc);
|
CGContextRelease(auxgc);
|
||||||
uchar *rgb3 = new uchar[3 * w * h]; // transform RGBA pixel array into RGB array
|
Fl_RGB_Image *rgb = new Fl_RGB_Image(rgba, w, h, 4);
|
||||||
uchar *p = rgba, *q = rgb3, *last = rgba + 4 * w * h;
|
|
||||||
while ( p < last) {
|
|
||||||
memcpy(q, p, 3);
|
|
||||||
p += 4;
|
|
||||||
q += 3;
|
|
||||||
}
|
|
||||||
delete[] rgba;
|
|
||||||
Fl_RGB_Image *rgb = new Fl_RGB_Image(rgb3, w, h, 3);
|
|
||||||
rgb->alloc_array = 1;
|
rgb->alloc_array = 1;
|
||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
@@ -484,16 +476,16 @@ Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int
|
|||||||
if (factor != 1) {
|
if (factor != 1) {
|
||||||
w *= factor; h *= factor; x *= factor; y *= factor;
|
w *= factor; h *= factor; x *= factor; y *= factor;
|
||||||
}
|
}
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
|
||||||
if (fl_mac_os_version >= 100600) {
|
if (fl_mac_os_version >= 100500) {
|
||||||
NSWindow *nswin = (NSWindow*)fl_mac_xid(pWindow);
|
NSWindow *nswin = (NSWindow*)fl_mac_xid(pWindow);
|
||||||
CGImageRef img_full = Fl_Cocoa_Window_Driver::capture_decorated_window_10_6(nswin);
|
CGImageRef img_full = Fl_Cocoa_Window_Driver::capture_decorated_window_10_5(nswin);
|
||||||
int bt = [nswin frame].size.height - [[nswin contentView] frame].size.height;
|
int bt = [nswin frame].size.height - [[nswin contentView] frame].size.height;
|
||||||
bt *= (factor / Fl_Graphics_Driver::default_driver().scale());
|
bt *= (factor / Fl_Graphics_Driver::default_driver().scale());
|
||||||
CGRect cgr = CGRectMake(x, y + bt, w, h); // add vertical offset to bypass titlebar
|
CGRect cgr = CGRectMake(x, y + bt, w, h); // add vertical offset to bypass titlebar
|
||||||
CGImageRef cgimg = CGImageCreateWithImageInRect(img_full, cgr); // 10.4
|
CGImageRef cgimg = CGImageCreateWithImageInRect(img_full, cgr); // 10.4
|
||||||
CGImageRelease(img_full);
|
CGImageRelease(img_full);
|
||||||
Fl_RGB_Image *rgb = cgimage_to_rgb3(cgimg);
|
Fl_RGB_Image *rgb = cgimage_to_rgb4(cgimg);
|
||||||
CGImageRelease(cgimg);
|
CGImageRelease(cgimg);
|
||||||
return rgb;
|
return rgb;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public:
|
|||||||
NSCursor *cursor;
|
NSCursor *cursor;
|
||||||
static void q_release_context(Fl_Cocoa_Window_Driver *x = 0); // free all resources associated with gc
|
static void q_release_context(Fl_Cocoa_Window_Driver *x = 0); // free all resources associated with gc
|
||||||
static void clip_to_rounded_corners(CGContextRef gc, int w, int h);
|
static void clip_to_rounded_corners(CGContextRef gc, int w, int h);
|
||||||
static CGImageRef capture_decorated_window_10_6(NSWindow *nswin);
|
static CGImageRef capture_decorated_window_10_5(NSWindow *nswin);
|
||||||
void set_key_window();
|
void set_key_window();
|
||||||
bool mapped_to_retina(); // is window mapped to retina display?
|
bool mapped_to_retina(); // is window mapped to retina display?
|
||||||
void mapped_to_retina(bool); // sets whether window is mapped to retina display
|
void mapped_to_retina(bool); // sets whether window is mapped to retina display
|
||||||
|
|||||||
Reference in New Issue
Block a user