From 7abda5a59b8bccd59138ea49e5866041cc482b8a Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Wed, 27 Dec 2017 13:51:41 +0000 Subject: GUI rescaling under MacOS: fix Fl_Cocoa_Screen_Driver::read_image() when reading from scaled offscreen buffer git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12609 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx | 30 +++++++++++++++++----- .../Quartz/Fl_Quartz_Image_Surface_Driver.cxx | 3 +++ 2 files changed, 27 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx index e4f86aa90..f03d399af 100644 --- a/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx +++ b/src/drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx @@ -280,25 +280,34 @@ int Fl_Cocoa_Screen_Driver::compose(int &del) { return 1; } -uchar * // O - Pixel buffer or NULL if failed -Fl_Cocoa_Screen_Driver::read_image(uchar *p, // I - Pixel buffer or NULL to allocate +uchar * // O - Pixel buffer or NULL if failed +Fl_Cocoa_Screen_Driver::read_image(uchar *p, // I - Pixel buffer or NULL to allocate int x, // I - Left position int y, // I - Top position int w, // I - Width of area to read int h, // I - Height of area to read - int alpha) // I - Alpha value for image (0 for none) + int alpha)// I - Alpha value for image (0 for none) { uchar *base; int rowBytes, delta; + float s = 1; + int ori_w = w, ori_h = h; if (fl_window == NULL) { // reading from an offscreen buffer CGContextRef src = (CGContextRef)Fl_Surface_Device::surface()->driver()->gc(); // get bitmap context base = (uchar *)CGBitmapContextGetData(src); // get data if(!base) return NULL; int sw = CGBitmapContextGetWidth(src); int sh = CGBitmapContextGetHeight(src); + if( (sw - x < w) || (sh - y < h) ) return NULL; rowBytes = CGBitmapContextGetBytesPerRow(src); delta = CGBitmapContextGetBitsPerPixel(src)/8; - if( (sw - x < w) || (sh - y < h) ) return NULL; + Fl_Image_Surface *imgs = (Fl_Image_Surface*)Fl_Surface_Device::surface(); + int fltk_w, fltk_h; + imgs->printable_rect(&fltk_w, &fltk_h); + s = sw / float(fltk_w); + x *= s; y *= s; w *= s; h *= s; + if (x + w > sw) w = sw - x; + if (y + h > sh) h = sh - y; } else { // reading from current window Fl_Cocoa_Window_Driver *d = Fl_Cocoa_Window_Driver::driver(Fl_Window::current()); @@ -313,7 +322,7 @@ Fl_Cocoa_Screen_Driver::read_image(uchar *p, // I - Pixel buffer or NULL to all // Initialize the default colors/alpha in the whole image... memset(p, alpha, w * h * d); // Copy the image from the off-screen buffer to the memory buffer. - int idx, idy; // Current X & Y in image + int idx, idy; // Current X & Y in image uchar *pdst, *psrc; for (idy = y, pdst = p; idy < h + y; idy ++) { for (idx = 0, psrc = base + idy * rowBytes + x * delta; idx < w; idx ++, psrc += delta, pdst += d) { @@ -322,7 +331,16 @@ Fl_Cocoa_Screen_Driver::read_image(uchar *p, // I - Pixel buffer or NULL to all pdst[2] = psrc[2]; // B } } - if(fl_window != NULL) delete[] base; + if (fl_window != NULL) delete[] base; + if (s != 1) { + Fl_RGB_Image *rgb = new Fl_RGB_Image(p, w, h, alpha ? 4 : 3); + rgb->alloc_array = 1; + Fl_RGB_Image *rgb2 = (Fl_RGB_Image*)rgb->copy(ori_w, ori_h); + rgb2->alloc_array = 0; + delete rgb; + p = (uchar*)rgb2->array; + delete rgb2; + } return p; } diff --git a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx index 573a5df8e..1702ca4ab 100644 --- a/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx +++ b/src/drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx @@ -104,7 +104,10 @@ Fl_RGB_Image* Fl_Quartz_Image_Surface_Driver::image() CGContextFlush(offscreen); int W = CGBitmapContextGetWidth(offscreen); int H = CGBitmapContextGetHeight(offscreen); + int save_w = width, save_h = height; + width = W; height = H; unsigned char *data = fl_read_image(NULL, 0, 0, W, H, 0); + width = save_w; height = save_h; Fl_RGB_Image *image = new Fl_RGB_Image(data, W, H); image->alloc_array = 1; return image; -- cgit v1.2.3