summaryrefslogtreecommitdiff
path: root/platform/darwin/src/MGLMapSnapshotter.mm
diff options
context:
space:
mode:
Diffstat (limited to 'platform/darwin/src/MGLMapSnapshotter.mm')
-rw-r--r--platform/darwin/src/MGLMapSnapshotter.mm150
1 files changed, 121 insertions, 29 deletions
diff --git a/platform/darwin/src/MGLMapSnapshotter.mm b/platform/darwin/src/MGLMapSnapshotter.mm
index dea93eba34..31b3ed41d6 100644
--- a/platform/darwin/src/MGLMapSnapshotter.mm
+++ b/platform/darwin/src/MGLMapSnapshotter.mm
@@ -27,6 +27,24 @@
const CGPoint MGLLogoImagePosition = CGPointMake(8, 8);
const CGFloat MGLSnapshotterMinimumPixelSize = 64;
+@interface MGLSnapshotAttributionOptions : NSObject
+#if TARGET_OS_IPHONE
+@property (nonatomic) UIImage *logoImage;
+#else
+@property (nonatomic) NSImage *logoImage;
+#endif
+
+@property (nonatomic) CGSize attributionBackgroundSize;
+
+@property (nonatomic) NS_ARRAY_OF(MGLAttributionInfo *) *attributionInfo;
+
+@end
+
+@implementation MGLSnapshotAttributionOptions
+@end
+
+
+
@implementation MGLMapSnapshotOptions
- (instancetype _Nonnull)initWithStyleURL:(nullable NSURL *)styleURL camera:(MGLMapCamera *)camera size:(CGSize) size
@@ -61,6 +79,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
@implementation MGLMapSnapshot {
mbgl::MapSnapshotter::PointForFn _pointForFn;
}
+
- (instancetype)initWithImage:(nullable MGLImage *)image scale:(CGFloat)scale pointForFn:(mbgl::MapSnapshotter::PointForFn)pointForFn
{
self = [super init];
@@ -88,6 +107,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
std::shared_ptr<mbgl::ThreadPool> _mbglThreadPool;
std::unique_ptr<mbgl::MapSnapshotter> _mbglMapSnapshotter;
std::unique_ptr<mbgl::Actor<mbgl::MapSnapshotter::Callback>> _snapshotCallback;
+ CGFloat _defaultLogoHeight;
}
- (instancetype)initWithOptions:(MGLMapSnapshotOptions *)options
@@ -167,15 +187,6 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[infos growArrayByAddingAttributionInfosFromArray:tileSetInfos];
}
- CGSize attributionBackgroundSize = CGSizeMake(10, 0);
- for (MGLAttributionInfo *info in infos) {
- if (info.isFeedbackLink) {
- continue;
- }
- attributionBackgroundSize.width += [info.title size].width + 10;
- attributionBackgroundSize.height = MAX([info.title size].height, attributionBackgroundSize.height);
- }
-
if (mbglError) {
NSString *description = @(mbgl::util::toString(mbglError).c_str());
NSDictionary *userInfo = @{NSLocalizedDescriptionKey: description};
@@ -198,20 +209,28 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
dispatch_queue_t workQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(workQueue, ^{
#if TARGET_OS_IPHONE
- UIImage *logoImage = [UIImage imageNamed:@"mapbox" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil];
+ MGLSnapshotAttributionOptions *option = [self attributionOptionsForSize:mglImage.size attributionInfo:infos];
+ UIImage *logoImage = option.logoImage;
CGRect logoImageRect = CGRectMake(MGLLogoImagePosition.x, mglImage.size.height - (MGLLogoImagePosition.y + logoImage.size.height), logoImage.size.width, logoImage.size.height);
- CGRect attributionBackgroundFrame = CGRectMake(mglImage.size.width - 10 - attributionBackgroundSize.width,
- logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2) + 1,
- attributionBackgroundSize.width,
- attributionBackgroundSize.height);
+ CGPoint attributionOrigin = CGPointMake(mglImage.size.width - 10 - option.attributionBackgroundSize.width,
+ logoImageRect.origin.y + (logoImageRect.size.height / 2) - (option.attributionBackgroundSize.height / 2) + 1);
+ if (!logoImage) {
+ logoImageRect = CGRectMake(0, mglImage.size.height - (MGLLogoImagePosition.y + _defaultLogoHeight), 0, _defaultLogoHeight);
+ attributionOrigin = CGPointMake(10, logoImageRect.origin.y + (logoImageRect.size.height / 2) - (option.attributionBackgroundSize.height / 2) + 1);
+ }
+
+ CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x,
+ attributionOrigin.y,
+ option.attributionBackgroundSize.width,
+ option.attributionBackgroundSize.height);
CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10,
attributionBackgroundFrame.origin.y - 1);
CGRect cropRect = CGRectMake(attributionBackgroundFrame.origin.x * mglImage.scale,
attributionBackgroundFrame.origin.y * mglImage.scale,
- attributionBackgroundSize.width * mglImage.scale,
- attributionBackgroundSize.height * mglImage.scale);
+ option.attributionBackgroundSize.width * mglImage.scale,
+ option.attributionBackgroundSize.height * mglImage.scale);
UIGraphicsBeginImageContextWithOptions(mglImage.size, NO, self.options.scale);
@@ -231,24 +250,32 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[blurredAttributionBackground drawInRect:attributionBackgroundFrame];
- [self drawAttributionText:infos origin:attributionTextPosition];
+ [self drawAttributionText:option.attributionInfo origin:attributionTextPosition];
UIImage *compositedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
#else
- NSImage *logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox" ofType:@"pdf"]];
- NSImage *sourceImage = mglImage;
-
NSSize targetSize = NSMakeSize(self.options.size.width, self.options.size.height);
NSRect targetFrame = NSMakeRect(0, 0, targetSize.width, targetSize.height);
+ MGLSnapshotAttributionOptions *option = [self attributionOptionsForSize:targetSize attributionInfo:infos];
+ NSImage *logoImage = option.logoImage;
+ NSImage *sourceImage = mglImage;
+
CGRect logoImageRect = CGRectMake(MGLLogoImagePosition.x, MGLLogoImagePosition.y, logoImage.size.width, logoImage.size.height);
- CGRect attributionBackgroundFrame = CGRectMake(targetFrame.size.width - 10 - attributionBackgroundSize.width,
- MGLLogoImagePosition.y + 1,
- attributionBackgroundSize.width,
- attributionBackgroundSize.height);
+ CGPoint attributionOrigin = CGPointMake(targetFrame.size.width - 10 - option.attributionBackgroundSize.width,
+ MGLLogoImagePosition.y + 1);
+ if (!logoImage) {
+ logoImageRect = CGRectMake(0, MGLLogoImagePosition.y, 0, _defaultLogoHeight);
+ attributionOrigin = CGPointMake(10, attributionOrigin.y);
+ }
+
+ CGRect attributionBackgroundFrame = CGRectMake(attributionOrigin.x,
+ attributionOrigin.y,
+ option.attributionBackgroundSize.width,
+ option.attributionBackgroundSize.height);
CGPoint attributionTextPosition = CGPointMake(attributionBackgroundFrame.origin.x + 10,
- logoImageRect.origin.y + (logoImageRect.size.height / 2) - (attributionBackgroundSize.height / 2));
+ logoImageRect.origin.y + (logoImageRect.size.height / 2) - (option.attributionBackgroundSize.height / 2));
NSImage *compositedImage = nil;
@@ -261,7 +288,9 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[sourceImageRep drawInRect: targetFrame];
- [logoImage drawInRect:logoImageRect];
+ if (logoImage) {
+ [logoImage drawInRect:logoImageRect];
+ }
NSBitmapImageRep *attributionBackground = [[NSBitmapImageRep alloc] initWithFocusedViewRect:attributionBackgroundFrame];
@@ -271,7 +300,7 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
[blurredAttributionBackground drawInRect:attributionBackgroundFrame];
- [self drawAttributionText:infos origin:attributionTextPosition];
+ [self drawAttributionText:option.attributionInfo origin:attributionTextPosition];
[compositedImage unlockFocus];
@@ -323,14 +352,77 @@ const CGFloat MGLSnapshotterMinimumPixelSize = 64;
CGImageRef cgimg = [ctx createCGImage:blurredImage fromRect:[backgroundImage extent]];
#if TARGET_OS_IPHONE
-
return [UIImage imageWithCGImage:cgimg];
#else
-
return [[NSImage alloc] initWithCGImage:cgimg size:[backgroundImage extent].size];
#endif
}
+- (MGLSnapshotAttributionOptions *)attributionOptionsForSize:(CGSize)snapshotSize attributionInfo:(NSArray *)attributionInfo
+{
+ NSMutableArray *options = [NSMutableArray array];
+ MGLSnapshotAttributionOptions *largeLogoAttribution = [self attributionOptionsForAttributionInfo:attributionInfo abbreviated:NO];
+#if TARGET_OS_IPHONE
+ largeLogoAttribution.logoImage = [UIImage imageNamed:@"mapbox" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil];
+#else
+ largeLogoAttribution.logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox" ofType:@"pdf"]];
+#endif
+ _defaultLogoHeight = largeLogoAttribution.logoImage.size.height;
+
+ MGLSnapshotAttributionOptions *smallLogoAttribution = [self attributionOptionsForAttributionInfo:attributionInfo abbreviated:NO];
+#if TARGET_OS_IPHONE
+ smallLogoAttribution.logoImage = [UIImage imageNamed:@"mapbox_helmet" inBundle:[NSBundle mgl_frameworkBundle] compatibleWithTraitCollection:nil];
+#else
+ smallLogoAttribution.logoImage = [[NSImage alloc] initWithContentsOfFile:[[NSBundle mgl_frameworkBundle] pathForResource:@"mapbox_helmet" ofType:@"pdf"]];
+#endif
+
+ MGLSnapshotAttributionOptions *noLogoAttribution = [self attributionOptionsForAttributionInfo:attributionInfo abbreviated:YES];
+
+ [options addObject:largeLogoAttribution];
+ [options addObject:smallLogoAttribution];
+ [options addObject:noLogoAttribution];
+
+ for (MGLSnapshotAttributionOptions *attributionOptions in options) {
+ // -[Mapbox Logo]-[Attribution Background]-
+ CGFloat origin = attributionOptions.logoImage ? MGLLogoImagePosition.x : 0;
+ CGFloat width = origin + attributionOptions.logoImage.size.width + 10 + attributionOptions.attributionBackgroundSize.width + 10;
+ if (width <= snapshotSize.width) {
+ return attributionOptions;
+ }
+ }
+
+ return noLogoAttribution;
+}
+
+- (MGLSnapshotAttributionOptions *)attributionOptionsForAttributionInfo:(NSArray *)attributionInfo abbreviated:(BOOL)isAbbreviated
+{
+ NSString *openStreetMap = NSLocalizedStringWithDefaultValue(@"OSM_FULL_NAME", nil, nil, @"OpenStreetMap", @"OpenStreetMap full name attribution");
+ NSString *OSM = NSLocalizedStringWithDefaultValue(@"OSM_SHORT_NAME", nil, nil, @"OSM", @"OpenStreetMap short name attribution");
+ NSMutableArray *infos = [NSMutableArray array];
+ CGSize attributionBackgroundSize = CGSizeMake(10, 0);
+ for (MGLAttributionInfo *info in attributionInfo) {
+ if (info.isFeedbackLink) {
+ continue;
+ }
+ MGLAttributionInfo *attribution = [info copy];
+ NSMutableAttributedString *title = [[NSMutableAttributedString alloc] initWithAttributedString:info.title];
+ [title removeAttribute:NSUnderlineStyleAttributeName range:NSMakeRange(0, [title.string length])];
+ if ([title.string rangeOfString:@"OpenStreetMap"].location != NSNotFound) {
+ [title.mutableString replaceOccurrencesOfString:@"OpenStreetMap" withString:isAbbreviated ? OSM : openStreetMap options:NSCaseInsensitiveSearch range:NSMakeRange(0, [title.mutableString length])];
+ }
+ attribution.title = title;
+ attributionBackgroundSize.width += [attribution.title size].width + 10;
+ attributionBackgroundSize.height = MAX([attribution.title size].height, attributionBackgroundSize.height);
+ [infos addObject:attribution];
+ }
+
+ MGLSnapshotAttributionOptions *attributionOptions = [[MGLSnapshotAttributionOptions alloc] init];
+ attributionOptions.attributionBackgroundSize = attributionBackgroundSize;
+ attributionOptions.attributionInfo = infos;
+
+ return attributionOptions;
+}
+
- (void)cancel
{
_snapshotCallback.reset();