From 727dd61553ec4fab90c8c35cd4013897a9314e55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Minh=20Nguye=CC=82=CC=83n?= Date: Sun, 6 Dec 2015 20:38:41 -0800 Subject: [osx] Printing Copied some pixel-reading code from HeadlessView. --- platform/osx/src/MGLMapView.mm | 50 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/platform/osx/src/MGLMapView.mm b/platform/osx/src/MGLMapView.mm index f80ef8fc7f..c563cf0ca9 100644 --- a/platform/osx/src/MGLMapView.mm +++ b/platform/osx/src/MGLMapView.mm @@ -196,6 +196,9 @@ public: BOOL _isTargetingInterfaceBuilder; CLLocationDegrees _pendingLatitude; CLLocationDegrees _pendingLongitude; + + /// True if the view is currently printing itself. + BOOL _isPrinting; } #pragma mark Lifecycle @@ -795,6 +798,21 @@ public: } } +#pragma mark Printing + +- (void)print:(__unused id)sender { + _isPrinting = YES; + [self invalidate]; +} + +- (void)printWithImage:(NSImage *)image { + NSImageView *imageView = [[NSImageView alloc] initWithFrame:self.bounds]; + imageView.image = image; + + NSPrintOperation *op = [NSPrintOperation printOperationWithView:imageView]; + [op runOperation]; +} + #pragma mark Viewport + (NS_SET_OF(NSString *) *)keyPathsForValuesAffectingCenterCoordinate { @@ -2213,7 +2231,37 @@ public: activate(); } - void afterRender() override {} + void afterRender() override { + if (nativeView->_isPrinting) { + nativeView->_isPrinting = NO; + std::string png = encodePNG(readStillImage()); + NSData *data = [[NSData alloc] initWithBytes:png.data() length:png.size()]; + NSImage *image = [[NSImage alloc] initWithData:data]; + [nativeView performSelectorOnMainThread:@selector(printWithImage:) + withObject:image + waitUntilDone:NO]; + } + } + + mbgl::PremultipliedImage readStillImage() override { + auto size = getFramebufferSize(); + const unsigned int w = size[0]; + const unsigned int h = size[1]; + + mbgl::PremultipliedImage image { w, h }; + MBGL_CHECK_ERROR(glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, image.data.get())); + + const int stride = image.stride(); + auto tmp = std::make_unique(stride); + uint8_t *rgba = image.data.get(); + for (int i = 0, j = h - 1; i < j; i++, j--) { + std::memcpy(tmp.get(), rgba + i * stride, stride); + std::memcpy(rgba + i * stride, rgba + j * stride, stride); + std::memcpy(rgba + j * stride, tmp.get(), stride); + } + + return image; + } private: /// Cocoa map view that this adapter bridges to. -- cgit v1.2.1