summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2014-12-12 17:12:11 +0000
committerManolo Gouy <Manolo>2014-12-12 17:12:11 +0000
commit00dd28afa4fbee63cc907d57f60b2c7d75355cfc (patch)
treeb57437462e3f67c0721471bb8a51d344bf4c0d5b
parente230a34cfdab9515fa3041a4947cc5b22afdf7e6 (diff)
Completed support of retina displays for Fl_Paged_Device::print_window_part().
Case with high resolution parent window and low resolution GL window is now directly processed. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10485 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
-rw-r--r--src/Fl_cocoa.mm121
1 files changed, 46 insertions, 75 deletions
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index eca0cbf70..06ba767ff 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -3830,6 +3830,36 @@ int Fl::dnd(void)
return true;
}
+// rescales an NSBitmapImageRep
+static NSBitmapImageRep *scale_nsbitmapimagerep(NSBitmapImageRep *img, float scale)
+{
+ int w = [img pixelsWide];
+ int h = [img pixelsHigh];
+ int scaled_w = int(scale * w + 0.5);
+ int scaled_h = int(scale * h + 0.5);
+ NSBitmapImageRep *scaled = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL
+ pixelsWide:scaled_w
+ pixelsHigh:scaled_h
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:scaled_w*4
+ bitsPerPixel:32];
+ NSDictionary *dict = [NSDictionary dictionaryWithObject:scaled
+ forKey:NSGraphicsContextDestinationAttributeName];
+ NSGraphicsContext *oldgc = [NSGraphicsContext currentContext];
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithAttributes:dict]];
+ [[NSColor clearColor] set];
+ NSRect r = NSMakeRect(0, 0, scaled_w, scaled_h);
+ NSRectFill(r);
+ [img drawInRect:r];
+ [NSGraphicsContext setCurrentContext:oldgc];
+ [img release];
+ return scaled;
+}
+
static void write_bitmap_inside(NSBitmapImageRep *to, int to_width, NSBitmapImageRep *from,
int to_x, int to_y)
/* Copies in bitmap "to" the bitmap "from" with its top-left angle at coordinates to_x, to_y
@@ -3862,88 +3892,25 @@ static void write_bitmap_inside(NSBitmapImageRep *to, int to_width, NSBitmapImag
}
}
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-static CGImageRef GL_rect_to_CGImage(Fl_Window *win, int x, int y, int w, int h)
-// to be used with Mac OS ≥ 10.6 to support retina displays
-// captures a rectangle from a GL window and returns it as a CGImageRef
-// with retina the image dimensions are 2*w,2*h
-// win is really a Fl_Gl_Window*
-{
- CGRect rect;
- NSRect r = [fl_xid(win) frame];
- rect = CGRectMake(r.origin.x + x, r.origin.y + win->h() - (y + h), w, h); // rect is target rect in window coordinates
- // convert r to global display coordinates
- rect.origin.y = CGDisplayPixelsHigh(CGMainDisplayID()) - (rect.origin.y + rect.size.height);
- uint32_t count;
- CGDirectDisplayID win_display;
- CGGetDisplaysWithPoint(rect.origin, 1, &win_display, &count); // find display containing the window
- CGRect bounds = CGDisplayBounds(win_display);
- rect.origin.x -= bounds.origin.x; // rect is now in local display coordinates
- rect.origin.y -= bounds.origin.y;
- return CGDisplayCreateImageForRect(win_display, rect); // Mac OS 10.6
-}
-#endif
-
-static void imgProviderReleaseData (void *info, const void *data, size_t size)
-{
- delete (Fl_RGB_Image *)info;
-}
-
-
-static CGImageRef GL_rect_to_CGImage_10_5(Fl_Window *win, int x, int y, int w, int h)
-// captures a rectangle from a GL window and returns it as a CGImageRef
-// used with Mac OS X 10.5 and before
-// win is really a Fl_Gl_Window*
+static NSBitmapImageRep* GL_rect_to_nsbitmap(Fl_Window *win, int x, int y, int w, int h)
+// captures a rectangle from a GL window and returns it as an allocated NSBitmapImageRep
{
Fl_Plugin_Manager pm("fltk:device");
Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
- if (!pi) return NULL;
+ if (!pi) return nil;
Fl_RGB_Image *img = pi->rectangle_capture(win, x, y, w, h);
- CGColorSpaceRef cSpace = CGColorSpaceCreateDeviceRGB();
- CGDataProviderRef provider = CGDataProviderCreateWithData(img, img->array, img->ld() * img->h(), imgProviderReleaseData);
- CGImageRef image = CGImageCreate(img->w(), img->h(), 8, 24, img->ld(), cSpace,
- (CGBitmapInfo)(kCGImageAlphaNone),
- provider, NULL, false, kCGRenderingIntentDefault);
- CGColorSpaceRelease(cSpace);
- CGDataProviderRelease(provider);
- if (image == NULL) delete img;
- return image;
-}
-
-
-static NSBitmapImageRep* GL_rect_to_nsbitmap(Fl_Window *win, int x, int y, int w, int h)
-// captures a rectangle from a GL window and returns it as an allocated NSBitmapImageRep
-{
- CGImageRef image;
- BOOL toflip = YES;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
- if (fl_mac_os_version >= 100600) {
- image = GL_rect_to_CGImage(win, x, y, w, h); // BGRA top to bottom
- toflip = NO;
- }
- else
-#endif
- image = GL_rect_to_CGImage_10_5(win, x, y, w, h); // RGB bottom to top
- if (!image) return nil;
- w = CGImageGetWidth(image);
- h = CGImageGetHeight(image);
- // convert image to RGBA writing it to a bitmap context
- Fl_Offscreen offscreen = fl_create_offscreen(w, h);
+ Fl_Offscreen offscreen = fl_create_offscreen(img->w(), img->h());
fl_begin_offscreen(offscreen);
- if (toflip) {
- CGContextTranslateCTM(fl_gc, 0, h);
- CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
- }
- CGRect rect = CGRectMake(0, 0, w, h);
- Fl_X::q_begin_image(rect, 0, 0, w, h);
- CGContextDrawImage(fl_gc, rect, image);
+ CGRect rect = CGRectMake(0, 0, img->w(), img->h());
+ Fl_X::q_begin_image(rect, 0, 0, img->w(), img->h()); // flip the image
+ img->draw(0, 0);
Fl_X::q_end_image();
- CGImageRelease(image);
fl_end_offscreen();
- NSBitmapImageRep* bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:NULL pixelsWide:w pixelsHigh:h bitsPerSample:8 samplesPerPixel:4 hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace bytesPerRow:4*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];
memcpy([bitmap bitmapData], CGBitmapContextGetData(offscreen), CGBitmapContextGetBytesPerRow(offscreen)*CGBitmapContextGetHeight(offscreen));
fl_delete_offscreen(offscreen);
+ delete img;
return bitmap;
}
@@ -3985,9 +3952,13 @@ static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y,
clip = CGRectIntersection(rsub, clip);
if (CGRectIsNull(clip)) continue;
NSBitmapImageRep *childbitmap = rect_to_NSBitmapImageRep(sub, clip.origin.x - sub->x(),
- win->h() - clip.origin.y - sub->y() - clip.size.height, clip.size.width, clip.size.height);
- if (childbitmap) write_bitmap_inside(bitmap, w, childbitmap,
- clip.origin.x - x, win->h() - clip.origin.y - clip.size.height - y );
+ win->h() - clip.origin.y - sub->y() - clip.size.height, clip.size.width, clip.size.height);
+ if (childbitmap) {
+ // if bitmap is high res and childbitmap is not, childbitmap must be rescaled
+ if ([bitmap pixelsWide] > w && [childbitmap pixelsWide] == clip.size.width) childbitmap = scale_nsbitmapimagerep(childbitmap, 2);
+ write_bitmap_inside(bitmap, w, childbitmap,
+ clip.origin.x - x, win->h() - clip.origin.y - clip.size.height - y );
+ }
[childbitmap release];
}
return bitmap;