diff options
author | Langston Smith <langston.smith@mapbox.com> | 2018-01-04 11:15:50 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-04 11:15:50 -0800 |
commit | 2ea955d2751ba6459f99a0695e53505c0a11702b (patch) | |
tree | f54450918b634a2eea1bd2c4ebc671bf1bb06106 /platform/macos/src | |
parent | f2ec6ae326bad79fea2b06a21151a2835522572a (diff) | |
parent | c62b0af24fc76b4bb2eb34100611dd3ee9ee5536 (diff) | |
download | qtlocation-mapboxgl-2ea955d2751ba6459f99a0695e53505c0a11702b.tar.gz |
Merge branch 'master' into ls-android-readme-tweaksupstream/ls-android-readme-tweaks
Diffstat (limited to 'platform/macos/src')
-rw-r--r-- | platform/macos/src/MGLMapView.h | 40 | ||||
-rw-r--r-- | platform/macos/src/MGLMapView.mm | 145 | ||||
-rw-r--r-- | platform/macos/src/MGLMapView_Private.h | 3 | ||||
-rw-r--r-- | platform/macos/src/Mapbox.h | 3 | ||||
-rw-r--r-- | platform/macos/src/NSImage+MGLAdditions.mm | 17 |
5 files changed, 135 insertions, 73 deletions
diff --git a/platform/macos/src/MGLMapView.h b/platform/macos/src/MGLMapView.h index 6bfdcfd100..de099157c8 100644 --- a/platform/macos/src/MGLMapView.h +++ b/platform/macos/src/MGLMapView.h @@ -10,6 +10,7 @@ NS_ASSUME_NONNULL_BEGIN @class MGLAnnotationImage; @class MGLMapCamera; @class MGLStyle; +@class MGLShape; @protocol MGLAnnotation; @protocol MGLMapViewDelegate; @@ -239,7 +240,7 @@ MGL_EXPORT IB_DESIGNABLE The default value of this property is 0. */ -@property (nonatomic) double minimumZoomLevel; +@property (nonatomic) IBInspectable double minimumZoomLevel; /** The maximum zoom level the map can be shown at. @@ -247,9 +248,10 @@ MGL_EXPORT IB_DESIGNABLE If the value of this property is smaller than that of the `minimumZoomLevel` property, the behavior is undefined. - The default value of this property is 20. + The default value of this property is 22. The upper bound for this property + is 25.5. */ -@property (nonatomic) double maximumZoomLevel; +@property (nonatomic) IBInspectable double maximumZoomLevel; /** Changes the zoom level of the map and optionally animates the change. @@ -321,6 +323,24 @@ MGL_EXPORT IB_DESIGNABLE */ - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion; + /** + Moves the viewpoint to a different location with respect to the map with an + optional transition duration and timing function. + + @param camera The new viewpoint. + @param duration The amount of time, measured in seconds, that the transition + animation should take. Specify `0` to jump to the new viewpoint + instantaneously. + @param function A timing function used for the animation. Set this parameter to + `nil` for a transition that matches most system animations. If the duration + is `0`, this parameter is ignored. + @param edgePadding The minimum padding (in screen points) that would be visible + around the returned camera object if it were set as the receiver’s camera. + @param completion The block to execute after the animation finishes. + */ +- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(NSEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion; + + /** Moves the viewpoint to a different location using a transition animation that evokes powered flight and a default duration based on the length of the flight @@ -456,6 +476,20 @@ MGL_EXPORT IB_DESIGNABLE - (MGLMapCamera *)cameraThatFitsCoordinateBounds:(MGLCoordinateBounds)bounds edgePadding:(NSEdgeInsets)insets; /** + Returns the camera that best fits the given shape, with the specified direction, + optionally with some additional padding on each side. + + @param shape The shape to fit to the receiver’s viewport. + @param direction The direction of the viewport, measured in degrees clockwise from true north. + @param insets The minimum padding (in screen points) that would be visible + around the returned camera object if it were set as the receiver’s camera. + @return A camera object centered on the shape's center with zoom level as high + (close to the ground) as possible while still including the entire shape. The + camera object uses the current pitch. + */ +- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(CLLocationDirection)direction edgePadding:(NSEdgeInsets)insets; + +/** A Boolean value indicating whether the receiver automatically adjusts its content insets. diff --git a/platform/macos/src/MGLMapView.mm b/platform/macos/src/MGLMapView.mm index 0a567a8510..b32edffd43 100644 --- a/platform/macos/src/MGLMapView.mm +++ b/platform/macos/src/MGLMapView.mm @@ -4,6 +4,8 @@ #import "MGLCompassCell.h" #import "MGLOpenGLLayer.h" #import "MGLStyle.h" +#import "MGLRendererFrontend.h" +#import "MGLRendererConfiguration.h" #import "MGLAnnotationImage_Private.h" #import "MGLAttributionInfo_Private.h" @@ -13,6 +15,7 @@ #import "MGLMultiPoint_Private.h" #import "MGLOfflineStorage_Private.h" #import "MGLStyle_Private.h" +#import "MGLShape_Private.h" #import "MGLAccountManager.h" #import "MGLMapCamera.h" @@ -23,15 +26,15 @@ #import "MGLImageSource.h" #import <mbgl/map/map.hpp> -#import <mbgl/map/view.hpp> #import <mbgl/style/style.hpp> #import <mbgl/annotation/annotation.hpp> #import <mbgl/map/camera.hpp> #import <mbgl/storage/reachability.h> #import <mbgl/util/default_thread_pool.hpp> -#import <mbgl/map/backend.hpp> -#import <mbgl/map/backend_scope.hpp> #import <mbgl/style/image.hpp> +#import <mbgl/renderer/renderer.hpp> +#import <mbgl/renderer/renderer_backend.hpp> +#import <mbgl/renderer/backend_scope.hpp> #import <mbgl/storage/default_file_source.hpp> #import <mbgl/storage/network_status.hpp> #import <mbgl/math/wrap.hpp> @@ -155,6 +158,7 @@ public: /// Cross-platform map view controller. mbgl::Map *_mbglMap; MGLMapViewImpl *_mbglView; + std::unique_ptr<MGLRenderFrontend> _rendererFrontend; std::shared_ptr<mbgl::ThreadPool> _mbglThreadPool; NSPanGestureRecognizer *_panGestureRecognizer; @@ -267,11 +271,12 @@ public: NSURL *legacyCacheURL = [cachesDirectoryURL URLByAppendingPathComponent:@"cache.db"]; [[NSFileManager defaultManager] removeItemAtURL:legacyCacheURL error:NULL]; - mbgl::DefaultFileSource* mbglFileSource = [MGLOfflineStorage sharedOfflineStorage].mbglFileSource; - _mbglThreadPool = mbgl::sharedThreadPool(); - _mbglMap = new mbgl::Map(*_mbglView, self.size, [NSScreen mainScreen].backingScaleFactor, *mbglFileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::GLContextMode::Unique, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); - [self validateTileCacheSize]; + MGLRendererConfiguration *config = [MGLRendererConfiguration currentConfiguration]; + + auto renderer = std::make_unique<mbgl::Renderer>(*_mbglView, config.scaleFactor, *config.fileSource, *_mbglThreadPool, config.contextMode, config.cacheDir, config.localFontFamilyName); + _rendererFrontend = std::make_unique<MGLRenderFrontend>(std::move(renderer), self, *_mbglView, true); + _mbglMap = new mbgl::Map(*_rendererFrontend, *_mbglView, self.size, config.scaleFactor, *config.fileSource, *_mbglThreadPool, mbgl::MapMode::Continuous, mbgl::ConstrainMode::None, mbgl::ViewportMode::Default); // Install the OpenGL layer. Interface Builder’s synchronous drawing means // we can’t display a map, so don’t even bother to have a map layer. @@ -643,6 +648,10 @@ public: return _mbglMap; } +- (mbgl::Renderer *)renderer { + return _rendererFrontend->getRenderer(); +} + #pragma mark View hierarchy and drawing - (void)viewWillMoveToWindow:(NSWindow *)newWindow { @@ -687,9 +696,6 @@ public: - (void)setFrame:(NSRect)frame { super.frame = frame; - if (!NSEqualRects(frame, self.frame)) { - [self validateTileCacheSize]; - } if (!_isTargetingInterfaceBuilder) { _mbglMap->setSize(self.size); } @@ -773,11 +779,8 @@ public: } - (void)renderSync { - if (!self.dormant) { - // The OpenGL implementation automatically enables the OpenGL context for us. - mbgl::BackendScope scope { *_mbglView, mbgl::BackendScope::ScopeType::Implicit }; - - _mbglMap->render(*_mbglView); + if (!self.dormant && _rendererFrontend) { + _rendererFrontend->render(); if (_isPrinting) { _isPrinting = NO; @@ -789,21 +792,6 @@ public: } } -- (void)validateTileCacheSize { - if (!_mbglMap) { - return; - } - - CGFloat zoomFactor = self.maximumZoomLevel - self.minimumZoomLevel + 1; - CGFloat cpuFactor = [NSProcessInfo processInfo].processorCount; - CGFloat memoryFactor = (CGFloat)[NSProcessInfo processInfo].physicalMemory / 1000 / 1000 / 1000; - CGFloat sizeFactor = (NSWidth(self.bounds) / mbgl::util::tileSize) * (NSHeight(self.bounds) / mbgl::util::tileSize); - - NSUInteger cacheSize = zoomFactor * cpuFactor * memoryFactor * sizeFactor * 0.5; - - _mbglMap->setSourceTileCacheSize(cacheSize); -} - - (void)setNeedsGLDisplay { MGLAssertIsMainThread(); @@ -1061,13 +1049,11 @@ public: - (void)setMinimumZoomLevel:(double)minimumZoomLevel { _mbglMap->setMinZoom(minimumZoomLevel); - [self validateTileCacheSize]; } - (void)setMaximumZoomLevel:(double)maximumZoomLevel { _mbglMap->setMaxZoom(maximumZoomLevel); - [self validateTileCacheSize]; } - (double)maximumZoomLevel { @@ -1136,6 +1122,10 @@ public: } - (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function completionHandler:(nullable void (^)(void))completion { + [self setCamera:camera withDuration:duration animationTimingFunction:function edgePadding:self.contentInsets completionHandler:completion]; +} + +- (void)setCamera:(MGLMapCamera *)camera withDuration:(NSTimeInterval)duration animationTimingFunction:(nullable CAMediaTimingFunction *)function edgePadding:(NSEdgeInsets)edgePadding completionHandler:(nullable void (^)(void))completion { mbgl::AnimationOptions animationOptions; if (duration > 0) { animationOptions.duration.emplace(MGLDurationFromTimeInterval(duration)); @@ -1163,7 +1153,7 @@ public: [self willChangeValueForKey:@"camera"]; _mbglMap->cancelTransitions(); - mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera]; + mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:edgePadding]; _mbglMap->easeTo(cameraOptions, animationOptions); [self didChangeValueForKey:@"camera"]; } @@ -1209,17 +1199,17 @@ public: [self willChangeValueForKey:@"camera"]; _mbglMap->cancelTransitions(); - mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera]; + mbgl::CameraOptions cameraOptions = [self cameraOptionsObjectForAnimatingToCamera:camera edgePadding:self.contentInsets]; _mbglMap->flyTo(cameraOptions, animationOptions); [self didChangeValueForKey:@"camera"]; } /// Returns a CameraOptions object that specifies parameters for animating to /// the given camera. -- (mbgl::CameraOptions)cameraOptionsObjectForAnimatingToCamera:(MGLMapCamera *)camera { +- (mbgl::CameraOptions)cameraOptionsObjectForAnimatingToCamera:(MGLMapCamera *)camera edgePadding:(NSEdgeInsets) edgePadding { mbgl::CameraOptions options; options.center = MGLLatLngFromLocationCoordinate2D(camera.centerCoordinate); - options.padding = MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets); + options.padding = MGLEdgeInsetsFromNSEdgeInsets(edgePadding); options.zoom = MGLZoomLevelForAltitude(camera.altitude, camera.pitch, camera.centerCoordinate.latitude, self.frame.size); @@ -1282,6 +1272,15 @@ public: return [self cameraForCameraOptions:cameraOptions]; } +- (MGLMapCamera *)cameraThatFitsShape:(MGLShape *)shape direction:(CLLocationDirection)direction edgePadding:(NSEdgeInsets)insets { + mbgl::EdgeInsets padding = MGLEdgeInsetsFromNSEdgeInsets(insets); + padding += MGLEdgeInsetsFromNSEdgeInsets(self.contentInsets); + + mbgl::CameraOptions cameraOptions = _mbglMap->cameraForGeometry([shape geometryObject], padding, direction); + + return [self cameraForCameraOptions:cameraOptions]; +} + - (MGLMapCamera *)cameraForCameraOptions:(const mbgl::CameraOptions &)cameraOptions { CLLocationCoordinate2D centerCoordinate = MGLLocationCoordinate2DFromLatLng(cameraOptions.center ? *cameraOptions.center : _mbglMap->getLatLng()); double zoomLevel = cameraOptions.zoom ? *cameraOptions.zoom : self.zoomLevel; @@ -1374,7 +1373,7 @@ public: // Move the cursor back to the start point and show it again, creating // the illusion that it has stayed in place during the entire gesture. CGPoint cursorPoint = [self convertPoint:startPoint toView:nil]; - cursorPoint = [self.window convertRectToScreen:{ startPoint, NSZeroSize }].origin; + cursorPoint = [self.window convertRectToScreen:{ cursorPoint, NSZeroSize }].origin; cursorPoint.y = self.window.screen.frame.size.height - cursorPoint.y; CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cursorPoint); CGDisplayShowCursor(kCGDirectMainDisplay); @@ -1489,7 +1488,7 @@ public: if (hitAnnotationTag != _selectedAnnotationTag) { id <MGLAnnotation> annotation = [self annotationWithTag:hitAnnotationTag]; NSAssert(annotation, @"Cannot select nonexistent annotation with tag %u", hitAnnotationTag); - [self selectAnnotation:annotation]; + [self selectAnnotation:annotation atPoint:gesturePoint]; } } else { [self deselectAnnotation:self.selectedAnnotation]; @@ -1792,6 +1791,12 @@ public: } std::vector<MGLAnnotationTag> annotationTags = [self annotationTagsInRect:rect]; + std::vector<MGLAnnotationTag> shapeAnnotationTags = [self shapeAnnotationTagsInRect:rect]; + + if (shapeAnnotationTags.size()) { + annotationTags.insert(annotationTags.end(), shapeAnnotationTags.begin(), shapeAnnotationTags.end()); + } + if (annotationTags.size()) { NSMutableArray *annotations = [NSMutableArray arrayWithCapacity:annotationTags.size()]; @@ -2051,13 +2056,18 @@ public: queryRect = NSInsetRect(queryRect, -MGLAnnotationImagePaddingForHitTest, -MGLAnnotationImagePaddingForHitTest); std::vector<MGLAnnotationTag> nearbyAnnotations = [self annotationTagsInRect:queryRect]; + std::vector<MGLAnnotationTag> nearbyShapeAnnotations = [self shapeAnnotationTagsInRect:queryRect]; + + if (nearbyShapeAnnotations.size()) { + nearbyAnnotations.insert(nearbyAnnotations.end(), nearbyShapeAnnotations.begin(), nearbyShapeAnnotations.end()); + } if (nearbyAnnotations.size()) { // Assume that the user is fat-fingering an annotation. NSRect hitRect = NSInsetRect({ point, NSZeroSize }, -MGLAnnotationImagePaddingForHitTest, -MGLAnnotationImagePaddingForHitTest); - + // Filter out any annotation whose image is unselectable or for which // hit testing fails. auto end = std::remove_if(nearbyAnnotations.begin(), nearbyAnnotations.end(), [&](const MGLAnnotationTag annotationTag) { @@ -2066,12 +2076,17 @@ public: if (!annotation) { return true; } - + + if ([annotation isKindOfClass:[MGLShape class]]) + { + return false; + } + MGLAnnotationImage *annotationImage = [self imageOfAnnotationWithTag:annotationTag]; if (!annotationImage.selectable) { return true; } - + // Filter out the annotation if the fattened finger didn’t land on a // translucent or opaque pixel in the image. NSRect annotationRect = [self frameOfImage:annotationImage.image @@ -2144,7 +2159,15 @@ public: /// Returns the tags of the annotations coincident with the given rectangle. - (std::vector<MGLAnnotationTag>)annotationTagsInRect:(NSRect)rect { // Cocoa origin is at the lower-left corner. - return _mbglMap->queryPointAnnotations({ + return self.renderer->queryPointAnnotations({ + { NSMinX(rect), NSHeight(self.bounds) - NSMaxY(rect) }, + { NSMaxX(rect), NSHeight(self.bounds) - NSMinY(rect) }, + }); +} + +- (std::vector<MGLAnnotationTag>)shapeAnnotationTagsInRect:(NSRect)rect { + // Cocoa origin is at the lower-left corner. + return _rendererFrontend->getRenderer()->queryShapeAnnotations({ { NSMinX(rect), NSHeight(self.bounds) - NSMaxY(rect) }, { NSMaxX(rect), NSHeight(self.bounds) - NSMinY(rect) }, }); @@ -2193,11 +2216,11 @@ public: - (void)selectAnnotation:(id <MGLAnnotation>)annotation { - // Only point annotations can be selected. - if (!annotation || [annotation isKindOfClass:[MGLMultiPoint class]]) { - return; - } + [self selectAnnotation:annotation atPoint:NSZeroPoint]; +} +- (void)selectAnnotation:(id <MGLAnnotation>)annotation atPoint:(NSPoint)gesturePoint +{ id <MGLAnnotation> selectedAnnotation = self.selectedAnnotation; if (annotation == selectedAnnotation) { return; @@ -2212,10 +2235,10 @@ public: [self addAnnotation:annotation]; } - // The annotation can’t be selected if no part of it is hittable. + // The annotation's anchor will bounce to the current click. NSRect positioningRect = [self positioningRectForCalloutForAnnotationWithTag:annotationTag]; if (NSIsEmptyRect(NSIntersectionRect(positioningRect, self.bounds))) { - return; + positioningRect = CGRectMake(gesturePoint.x, gesturePoint.y, positioningRect.size.width, positioningRect.size.height); } self.selectedAnnotation = annotation; @@ -2315,6 +2338,13 @@ public: if (!annotation) { return NSZeroRect; } + if ([annotation isKindOfClass:[MGLMultiPoint class]]) { + CLLocationCoordinate2D origin = annotation.coordinate; + CGPoint originPoint = [self convertCoordinate:origin toPointToView:self]; + return CGRectMake(originPoint.x, originPoint.y, MGLAnnotationImagePaddingForHitTest, MGLAnnotationImagePaddingForHitTest); + + } + NSImage *image = [self imageOfAnnotationWithTag:annotationTag].image; if (!image) { image = [self dequeueReusableAnnotationImageWithIdentifier:MGLDefaultStyleMarkerSymbolName].image; @@ -2565,7 +2595,7 @@ public: optionalFilter = predicate.mgl_filter; } - std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs, optionalFilter }); + std::vector<mbgl::Feature> features = _rendererFrontend->getRenderer()->queryRenderedFeatures(screenCoordinate, { optionalLayerIDs, optionalFilter }); return MGLFeaturesFromMBGLFeatures(features); } @@ -2599,7 +2629,7 @@ public: optionalFilter = predicate.mgl_filter; } - std::vector<mbgl::Feature> features = _mbglMap->queryRenderedFeatures(screenBox, { optionalLayerIDs, optionalFilter }); + std::vector<mbgl::Feature> features = _rendererFrontend->getRenderer()->queryRenderedFeatures(screenBox, { optionalLayerIDs, optionalFilter }); return MGLFeaturesFromMBGLFeatures(features); } @@ -2777,10 +2807,9 @@ public: } /// Adapter responsible for bridging calls from mbgl to MGLMapView and Cocoa. -class MGLMapViewImpl : public mbgl::View, public mbgl::Backend { +class MGLMapViewImpl : public mbgl::RendererBackend, public mbgl::MapObserver { public: - MGLMapViewImpl(MGLMapView *nativeView_) - : nativeView(nativeView_) {} + MGLMapViewImpl(MGLMapView *nativeView_) : nativeView(nativeView_) {} void onCameraWillChange(mbgl::MapObserver::CameraChangeMode mode) override { bool animated = mode == mbgl::MapObserver::CameraChangeMode::Animated; @@ -2858,7 +2887,7 @@ public: [nativeView sourceDidChange:nativeSource]; } - mbgl::gl::ProcAddress initializeExtension(const char* name) override { + mbgl::gl::ProcAddress getExtensionFunctionPointer(const char* name) override { static CFBundleRef framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); if (!framework) { throw std::runtime_error("Failed to load OpenGL framework."); @@ -2871,10 +2900,6 @@ public: return reinterpret_cast<mbgl::gl::ProcAddress>(symbol); } - void invalidate() override { - [nativeView setNeedsGLDisplay]; - } - void activate() override { if (activationCount++) { return; @@ -2903,6 +2928,10 @@ public: setViewport(0, 0, nativeView.framebufferSize); } + mbgl::Size getFramebufferSize() const override { + return nativeView.framebufferSize; + } + mbgl::PremultipliedImage readStillImage() { return readFramebuffer(nativeView.framebufferSize); } diff --git a/platform/macos/src/MGLMapView_Private.h b/platform/macos/src/MGLMapView_Private.h index 5ac75768a1..f2d178bc31 100644 --- a/platform/macos/src/MGLMapView_Private.h +++ b/platform/macos/src/MGLMapView_Private.h @@ -2,6 +2,7 @@ namespace mbgl { class Map; + class Renderer; } @interface MGLMapView (Private) @@ -29,4 +30,6 @@ namespace mbgl { - (mbgl::Map *)mbglMap; +- (mbgl::Renderer *)renderer; + @end diff --git a/platform/macos/src/Mapbox.h b/platform/macos/src/Mapbox.h index e4ad258b6e..26c67d5550 100644 --- a/platform/macos/src/Mapbox.h +++ b/platform/macos/src/Mapbox.h @@ -49,6 +49,8 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[]; #import "MGLTileSource.h" #import "MGLVectorSource.h" #import "MGLShapeSource.h" +#import "MGLAbstractShapeSource.h" +#import "MGLComputedShapeSource.h" #import "MGLRasterSource.h" #import "MGLImageSource.h" #import "MGLTilePyramidOfflineRegion.h" @@ -56,3 +58,4 @@ FOUNDATION_EXPORT MGL_EXPORT const unsigned char MapboxVersionString[]; #import "NSValue+MGLAdditions.h" #import "MGLStyleValue.h" #import "MGLAttributionInfo.h" +#import "MGLMapSnapshotter.h" diff --git a/platform/macos/src/NSImage+MGLAdditions.mm b/platform/macos/src/NSImage+MGLAdditions.mm index 6abe53e9ae..2666dfe790 100644 --- a/platform/macos/src/NSImage+MGLAdditions.mm +++ b/platform/macos/src/NSImage+MGLAdditions.mm @@ -5,7 +5,7 @@ @implementation NSImage (MGLAdditions) - (nullable instancetype)initWithMGLPremultipliedImage:(mbgl::PremultipliedImage&&)src { - CGImageRef image = CGImageFromMGLPremultipliedImage(std::move(src)); + CGImageRef image = CGImageCreateWithMGLPremultipliedImage(std::move(src)); if (!image) { return nil; } @@ -16,7 +16,7 @@ } - (nullable instancetype)initWithMGLStyleImage:(const mbgl::style::Image *)styleImage { - CGImageRef image = CGImageFromMGLPremultipliedImage(styleImage->getImage().clone()); + CGImageRef image = CGImageCreateWithMGLPremultipliedImage(styleImage->getImage().clone()); if (!image) { return nil; } @@ -42,15 +42,8 @@ } - (mbgl::PremultipliedImage)mgl_premultipliedImage { - // Create a bitmap image representation from the image, respecting backing - // scale factor and any resizing done on the image at runtime. - // http://www.cocoabuilder.com/archive/cocoa/82430-nsimage-getting-raw-bitmap-data.html#82431 - [self lockFocus]; - NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:{ NSZeroPoint, self.size }]; - [self unlockFocus]; - - mbgl::PremultipliedImage cPremultipliedImage({ static_cast<uint32_t>(rep.pixelsWide), static_cast<uint32_t>(rep.pixelsHigh) }); - std::copy(rep.bitmapData, rep.bitmapData + cPremultipliedImage.bytes(), cPremultipliedImage.data.get()); - return cPremultipliedImage; + CGImageRef ref = [self CGImageForProposedRect:nullptr context:nullptr hints:nullptr]; + return MGLPremultipliedImageFromCGImage(ref); } + @end |